1 // SPDX-License-Identifier: (GPL-2.0 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/firmware.h> 12 #include <sound/tlv.h> 13 #include <sound/pcm_params.h> 14 #include <uapi/sound/sof/tokens.h> 15 #include "sof-priv.h" 16 #include "ops.h" 17 18 #define COMP_ID_UNASSIGNED 0xffffffff 19 /* 20 * Constants used in the computation of linear volume gain 21 * from dB gain 20th root of 10 in Q1.16 fixed-point notation 22 */ 23 #define VOL_TWENTIETH_ROOT_OF_TEN 73533 24 /* 40th root of 10 in Q1.16 fixed-point notation*/ 25 #define VOL_FORTIETH_ROOT_OF_TEN 69419 26 /* 27 * Volume fractional word length define to 16 sets 28 * the volume linear gain value to use Qx.16 format 29 */ 30 #define VOLUME_FWL 16 31 /* 0.5 dB step value in topology TLV */ 32 #define VOL_HALF_DB_STEP 50 33 /* Full volume for default values */ 34 #define VOL_ZERO_DB BIT(VOLUME_FWL) 35 36 /* TLV data items */ 37 #define TLV_ITEMS 3 38 #define TLV_MIN 0 39 #define TLV_STEP 1 40 #define TLV_MUTE 2 41 42 /* size of tplg abi in byte */ 43 #define SOF_TPLG_ABI_SIZE 3 44 45 /* send pcm params ipc */ 46 static int ipc_pcm_params(struct snd_sof_widget *swidget, int dir) 47 { 48 struct sof_ipc_pcm_params_reply ipc_params_reply; 49 struct snd_sof_dev *sdev = swidget->sdev; 50 struct sof_ipc_pcm_params pcm; 51 struct snd_pcm_hw_params *params; 52 struct snd_sof_pcm *spcm; 53 int ret = 0; 54 55 memset(&pcm, 0, sizeof(pcm)); 56 57 /* get runtime PCM params using widget's stream name */ 58 spcm = snd_sof_find_spcm_name(sdev, swidget->widget->sname); 59 if (!spcm) { 60 dev_err(sdev->dev, "error: cannot find PCM for %s\n", 61 swidget->widget->name); 62 return -EINVAL; 63 } 64 65 params = &spcm->params[dir]; 66 67 /* set IPC PCM params */ 68 pcm.hdr.size = sizeof(pcm); 69 pcm.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_PARAMS; 70 pcm.comp_id = swidget->comp_id; 71 pcm.params.hdr.size = sizeof(pcm.params); 72 pcm.params.direction = dir; 73 pcm.params.sample_valid_bytes = params_width(params) >> 3; 74 pcm.params.buffer_fmt = SOF_IPC_BUFFER_INTERLEAVED; 75 pcm.params.rate = params_rate(params); 76 pcm.params.channels = params_channels(params); 77 pcm.params.host_period_bytes = params_period_bytes(params); 78 79 /* set format */ 80 switch (params_format(params)) { 81 case SNDRV_PCM_FORMAT_S16: 82 pcm.params.frame_fmt = SOF_IPC_FRAME_S16_LE; 83 break; 84 case SNDRV_PCM_FORMAT_S24: 85 pcm.params.frame_fmt = SOF_IPC_FRAME_S24_4LE; 86 break; 87 case SNDRV_PCM_FORMAT_S32: 88 pcm.params.frame_fmt = SOF_IPC_FRAME_S32_LE; 89 break; 90 default: 91 return -EINVAL; 92 } 93 94 /* send IPC to the DSP */ 95 ret = sof_ipc_tx_message(sdev->ipc, pcm.hdr.cmd, &pcm, sizeof(pcm), 96 &ipc_params_reply, sizeof(ipc_params_reply)); 97 if (ret < 0) 98 dev_err(sdev->dev, "error: pcm params failed for %s\n", 99 swidget->widget->name); 100 101 return ret; 102 } 103 104 /* send stream trigger ipc */ 105 static int ipc_trigger(struct snd_sof_widget *swidget, int cmd) 106 { 107 struct snd_sof_dev *sdev = swidget->sdev; 108 struct sof_ipc_stream stream; 109 struct sof_ipc_reply reply; 110 int ret = 0; 111 112 /* set IPC stream params */ 113 stream.hdr.size = sizeof(stream); 114 stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | cmd; 115 stream.comp_id = swidget->comp_id; 116 117 /* send IPC to the DSP */ 118 ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream, 119 sizeof(stream), &reply, sizeof(reply)); 120 if (ret < 0) 121 dev_err(sdev->dev, "error: failed to trigger %s\n", 122 swidget->widget->name); 123 124 return ret; 125 } 126 127 static int sof_keyword_dapm_event(struct snd_soc_dapm_widget *w, 128 struct snd_kcontrol *k, int event) 129 { 130 struct snd_sof_widget *swidget = w->dobj.private; 131 struct snd_sof_dev *sdev; 132 int ret = 0; 133 134 if (!swidget) 135 return 0; 136 137 sdev = swidget->sdev; 138 139 dev_dbg(sdev->dev, "received event %d for widget %s\n", 140 event, w->name); 141 142 /* process events */ 143 switch (event) { 144 case SND_SOC_DAPM_PRE_PMU: 145 /* set pcm params */ 146 ret = ipc_pcm_params(swidget, SOF_IPC_STREAM_CAPTURE); 147 if (ret < 0) { 148 dev_err(sdev->dev, 149 "error: failed to set pcm params for widget %s\n", 150 swidget->widget->name); 151 break; 152 } 153 154 /* start trigger */ 155 ret = ipc_trigger(swidget, SOF_IPC_STREAM_TRIG_START); 156 if (ret < 0) 157 dev_err(sdev->dev, 158 "error: failed to trigger widget %s\n", 159 swidget->widget->name); 160 break; 161 case SND_SOC_DAPM_POST_PMD: 162 /* stop trigger */ 163 ret = ipc_trigger(swidget, SOF_IPC_STREAM_TRIG_STOP); 164 if (ret < 0) 165 dev_err(sdev->dev, 166 "error: failed to trigger widget %s\n", 167 swidget->widget->name); 168 169 /* pcm free */ 170 ret = ipc_trigger(swidget, SOF_IPC_STREAM_PCM_FREE); 171 if (ret < 0) 172 dev_err(sdev->dev, 173 "error: failed to trigger widget %s\n", 174 swidget->widget->name); 175 break; 176 default: 177 break; 178 } 179 180 return ret; 181 } 182 183 /* event handlers for keyword detect component */ 184 static const struct snd_soc_tplg_widget_events sof_kwd_events[] = { 185 {SOF_KEYWORD_DETECT_DAPM_EVENT, sof_keyword_dapm_event}, 186 }; 187 188 static inline int get_tlv_data(const int *p, int tlv[TLV_ITEMS]) 189 { 190 /* we only support dB scale TLV type at the moment */ 191 if ((int)p[SNDRV_CTL_TLVO_TYPE] != SNDRV_CTL_TLVT_DB_SCALE) 192 return -EINVAL; 193 194 /* min value in topology tlv data is multiplied by 100 */ 195 tlv[TLV_MIN] = (int)p[SNDRV_CTL_TLVO_DB_SCALE_MIN] / 100; 196 197 /* volume steps */ 198 tlv[TLV_STEP] = (int)(p[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] & 199 TLV_DB_SCALE_MASK); 200 201 /* mute ON/OFF */ 202 if ((p[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] & 203 TLV_DB_SCALE_MUTE) == 0) 204 tlv[TLV_MUTE] = 0; 205 else 206 tlv[TLV_MUTE] = 1; 207 208 return 0; 209 } 210 211 /* 212 * Function to truncate an unsigned 64-bit number 213 * by x bits and return 32-bit unsigned number. This 214 * function also takes care of rounding while truncating 215 */ 216 static inline u32 vol_shift_64(u64 i, u32 x) 217 { 218 /* do not truncate more than 32 bits */ 219 if (x > 32) 220 x = 32; 221 222 if (x == 0) 223 return (u32)i; 224 225 return (u32)(((i >> (x - 1)) + 1) >> 1); 226 } 227 228 /* 229 * Function to compute a ^ exp where, 230 * a is a fractional number represented by a fixed-point 231 * integer with a fractional world length of "fwl" 232 * exp is an integer 233 * fwl is the fractional word length 234 * Return value is a fractional number represented by a 235 * fixed-point integer with a fractional word length of "fwl" 236 */ 237 static u32 vol_pow32(u32 a, int exp, u32 fwl) 238 { 239 int i, iter; 240 u32 power = 1 << fwl; 241 u64 numerator; 242 243 /* if exponent is 0, return 1 */ 244 if (exp == 0) 245 return power; 246 247 /* determine the number of iterations based on the exponent */ 248 if (exp < 0) 249 iter = exp * -1; 250 else 251 iter = exp; 252 253 /* mutiply a "iter" times to compute power */ 254 for (i = 0; i < iter; i++) { 255 /* 256 * Product of 2 Qx.fwl fixed-point numbers yields a Q2*x.2*fwl 257 * Truncate product back to fwl fractional bits with rounding 258 */ 259 power = vol_shift_64((u64)power * a, fwl); 260 } 261 262 if (exp > 0) { 263 /* if exp is positive, return the result */ 264 return power; 265 } 266 267 /* if exp is negative, return the multiplicative inverse */ 268 numerator = (u64)1 << (fwl << 1); 269 do_div(numerator, power); 270 271 return (u32)numerator; 272 } 273 274 /* 275 * Function to calculate volume gain from TLV data. 276 * This function can only handle gain steps that are multiples of 0.5 dB 277 */ 278 static u32 vol_compute_gain(u32 value, int *tlv) 279 { 280 int dB_gain; 281 u32 linear_gain; 282 int f_step; 283 284 /* mute volume */ 285 if (value == 0 && tlv[TLV_MUTE]) 286 return 0; 287 288 /* 289 * compute dB gain from tlv. tlv_step 290 * in topology is multiplied by 100 291 */ 292 dB_gain = tlv[TLV_MIN] + (value * tlv[TLV_STEP]) / 100; 293 294 /* 295 * compute linear gain represented by fixed-point 296 * int with VOLUME_FWL fractional bits 297 */ 298 linear_gain = vol_pow32(VOL_TWENTIETH_ROOT_OF_TEN, dB_gain, VOLUME_FWL); 299 300 /* extract the fractional part of volume step */ 301 f_step = tlv[TLV_STEP] - (tlv[TLV_STEP] / 100); 302 303 /* if volume step is an odd multiple of 0.5 dB */ 304 if (f_step == VOL_HALF_DB_STEP && (value & 1)) 305 linear_gain = vol_shift_64((u64)linear_gain * 306 VOL_FORTIETH_ROOT_OF_TEN, 307 VOLUME_FWL); 308 309 return linear_gain; 310 } 311 312 /* 313 * Set up volume table for kcontrols from tlv data 314 * "size" specifies the number of entries in the table 315 */ 316 static int set_up_volume_table(struct snd_sof_control *scontrol, 317 int tlv[TLV_ITEMS], int size) 318 { 319 int j; 320 321 /* init the volume table */ 322 scontrol->volume_table = kcalloc(size, sizeof(u32), GFP_KERNEL); 323 if (!scontrol->volume_table) 324 return -ENOMEM; 325 326 /* populate the volume table */ 327 for (j = 0; j < size ; j++) 328 scontrol->volume_table[j] = vol_compute_gain(j, tlv); 329 330 return 0; 331 } 332 333 struct sof_dai_types { 334 const char *name; 335 enum sof_ipc_dai_type type; 336 }; 337 338 static const struct sof_dai_types sof_dais[] = { 339 {"SSP", SOF_DAI_INTEL_SSP}, 340 {"HDA", SOF_DAI_INTEL_HDA}, 341 {"DMIC", SOF_DAI_INTEL_DMIC}, 342 }; 343 344 static enum sof_ipc_dai_type find_dai(const char *name) 345 { 346 int i; 347 348 for (i = 0; i < ARRAY_SIZE(sof_dais); i++) { 349 if (strcmp(name, sof_dais[i].name) == 0) 350 return sof_dais[i].type; 351 } 352 353 return SOF_DAI_INTEL_NONE; 354 } 355 356 /* 357 * Supported Frame format types and lookup, add new ones to end of list. 358 */ 359 360 struct sof_frame_types { 361 const char *name; 362 enum sof_ipc_frame frame; 363 }; 364 365 static const struct sof_frame_types sof_frames[] = { 366 {"s16le", SOF_IPC_FRAME_S16_LE}, 367 {"s24le", SOF_IPC_FRAME_S24_4LE}, 368 {"s32le", SOF_IPC_FRAME_S32_LE}, 369 {"float", SOF_IPC_FRAME_FLOAT}, 370 }; 371 372 static enum sof_ipc_frame find_format(const char *name) 373 { 374 int i; 375 376 for (i = 0; i < ARRAY_SIZE(sof_frames); i++) { 377 if (strcmp(name, sof_frames[i].name) == 0) 378 return sof_frames[i].frame; 379 } 380 381 /* use s32le if nothing is specified */ 382 return SOF_IPC_FRAME_S32_LE; 383 } 384 385 struct sof_process_types { 386 const char *name; 387 enum sof_ipc_process_type type; 388 enum sof_comp_type comp_type; 389 }; 390 391 static const struct sof_process_types sof_process[] = { 392 {"EQFIR", SOF_PROCESS_EQFIR, SOF_COMP_EQ_FIR}, 393 {"EQIIR", SOF_PROCESS_EQIIR, SOF_COMP_EQ_IIR}, 394 {"KEYWORD_DETECT", SOF_PROCESS_KEYWORD_DETECT, SOF_COMP_KEYWORD_DETECT}, 395 {"KPB", SOF_PROCESS_KPB, SOF_COMP_KPB}, 396 {"CHAN_SELECTOR", SOF_PROCESS_CHAN_SELECTOR, SOF_COMP_SELECTOR}, 397 }; 398 399 static enum sof_ipc_process_type find_process(const char *name) 400 { 401 int i; 402 403 for (i = 0; i < ARRAY_SIZE(sof_process); i++) { 404 if (strcmp(name, sof_process[i].name) == 0) 405 return sof_process[i].type; 406 } 407 408 return SOF_PROCESS_NONE; 409 } 410 411 static enum sof_comp_type find_process_comp_type(enum sof_ipc_process_type type) 412 { 413 int i; 414 415 for (i = 0; i < ARRAY_SIZE(sof_process); i++) { 416 if (sof_process[i].type == type) 417 return sof_process[i].comp_type; 418 } 419 420 return SOF_COMP_NONE; 421 } 422 423 /* 424 * Standard Kcontrols. 425 */ 426 427 static int sof_control_load_volume(struct snd_soc_component *scomp, 428 struct snd_sof_control *scontrol, 429 struct snd_kcontrol_new *kc, 430 struct snd_soc_tplg_ctl_hdr *hdr) 431 { 432 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 433 struct snd_soc_tplg_mixer_control *mc = 434 container_of(hdr, struct snd_soc_tplg_mixer_control, hdr); 435 struct sof_ipc_ctrl_data *cdata; 436 int tlv[TLV_ITEMS]; 437 unsigned int i; 438 int ret; 439 440 /* validate topology data */ 441 if (le32_to_cpu(mc->num_channels) > SND_SOC_TPLG_MAX_CHAN) 442 return -EINVAL; 443 444 /* init the volume get/put data */ 445 scontrol->size = sizeof(struct sof_ipc_ctrl_data) + 446 sizeof(struct sof_ipc_ctrl_value_chan) * 447 le32_to_cpu(mc->num_channels); 448 scontrol->control_data = kzalloc(scontrol->size, GFP_KERNEL); 449 if (!scontrol->control_data) 450 return -ENOMEM; 451 452 scontrol->comp_id = sdev->next_comp_id; 453 scontrol->num_channels = le32_to_cpu(mc->num_channels); 454 455 /* set cmd for mixer control */ 456 if (le32_to_cpu(mc->max) == 1) { 457 scontrol->cmd = SOF_CTRL_CMD_SWITCH; 458 goto out; 459 } 460 461 scontrol->cmd = SOF_CTRL_CMD_VOLUME; 462 463 /* extract tlv data */ 464 if (get_tlv_data(kc->tlv.p, tlv) < 0) { 465 dev_err(sdev->dev, "error: invalid TLV data\n"); 466 return -EINVAL; 467 } 468 469 /* set up volume table */ 470 ret = set_up_volume_table(scontrol, tlv, le32_to_cpu(mc->max) + 1); 471 if (ret < 0) { 472 dev_err(sdev->dev, "error: setting up volume table\n"); 473 return ret; 474 } 475 476 /* set default volume values to 0dB in control */ 477 cdata = scontrol->control_data; 478 for (i = 0; i < scontrol->num_channels; i++) { 479 cdata->chanv[i].channel = i; 480 cdata->chanv[i].value = VOL_ZERO_DB; 481 } 482 483 out: 484 dev_dbg(sdev->dev, "tplg: load kcontrol index %d chans %d\n", 485 scontrol->comp_id, scontrol->num_channels); 486 487 return 0; 488 } 489 490 static int sof_control_load_enum(struct snd_soc_component *scomp, 491 struct snd_sof_control *scontrol, 492 struct snd_kcontrol_new *kc, 493 struct snd_soc_tplg_ctl_hdr *hdr) 494 { 495 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 496 struct snd_soc_tplg_enum_control *ec = 497 container_of(hdr, struct snd_soc_tplg_enum_control, hdr); 498 499 /* validate topology data */ 500 if (le32_to_cpu(ec->num_channels) > SND_SOC_TPLG_MAX_CHAN) 501 return -EINVAL; 502 503 /* init the enum get/put data */ 504 scontrol->size = sizeof(struct sof_ipc_ctrl_data) + 505 sizeof(struct sof_ipc_ctrl_value_chan) * 506 le32_to_cpu(ec->num_channels); 507 scontrol->control_data = kzalloc(scontrol->size, GFP_KERNEL); 508 if (!scontrol->control_data) 509 return -ENOMEM; 510 511 scontrol->comp_id = sdev->next_comp_id; 512 scontrol->num_channels = le32_to_cpu(ec->num_channels); 513 514 scontrol->cmd = SOF_CTRL_CMD_ENUM; 515 516 dev_dbg(sdev->dev, "tplg: load kcontrol index %d chans %d comp_id %d\n", 517 scontrol->comp_id, scontrol->num_channels, scontrol->comp_id); 518 519 return 0; 520 } 521 522 static int sof_control_load_bytes(struct snd_soc_component *scomp, 523 struct snd_sof_control *scontrol, 524 struct snd_kcontrol_new *kc, 525 struct snd_soc_tplg_ctl_hdr *hdr) 526 { 527 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 528 struct sof_ipc_ctrl_data *cdata; 529 struct snd_soc_tplg_bytes_control *control = 530 container_of(hdr, struct snd_soc_tplg_bytes_control, hdr); 531 struct soc_bytes_ext *sbe = (struct soc_bytes_ext *)kc->private_value; 532 int max_size = sbe->max; 533 534 if (le32_to_cpu(control->priv.size) > max_size) { 535 dev_err(sdev->dev, "err: bytes data size %d exceeds max %d.\n", 536 control->priv.size, max_size); 537 return -EINVAL; 538 } 539 540 /* init the get/put bytes data */ 541 scontrol->size = sizeof(struct sof_ipc_ctrl_data) + 542 le32_to_cpu(control->priv.size); 543 scontrol->control_data = kzalloc(max_size, GFP_KERNEL); 544 cdata = scontrol->control_data; 545 if (!scontrol->control_data) 546 return -ENOMEM; 547 548 scontrol->comp_id = sdev->next_comp_id; 549 scontrol->cmd = SOF_CTRL_CMD_BINARY; 550 551 dev_dbg(sdev->dev, "tplg: load kcontrol index %d chans %d\n", 552 scontrol->comp_id, scontrol->num_channels); 553 554 if (le32_to_cpu(control->priv.size) > 0) { 555 memcpy(cdata->data, control->priv.data, 556 le32_to_cpu(control->priv.size)); 557 558 if (cdata->data->magic != SOF_ABI_MAGIC) { 559 dev_err(sdev->dev, "error: Wrong ABI magic 0x%08x.\n", 560 cdata->data->magic); 561 return -EINVAL; 562 } 563 if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, 564 cdata->data->abi)) { 565 dev_err(sdev->dev, 566 "error: Incompatible ABI version 0x%08x.\n", 567 cdata->data->abi); 568 return -EINVAL; 569 } 570 if (cdata->data->size + sizeof(const struct sof_abi_hdr) != 571 le32_to_cpu(control->priv.size)) { 572 dev_err(sdev->dev, 573 "error: Conflict in bytes vs. priv size.\n"); 574 return -EINVAL; 575 } 576 } 577 return 0; 578 } 579 580 /* 581 * Topology Token Parsing. 582 * New tokens should be added to headers and parsing tables below. 583 */ 584 585 struct sof_topology_token { 586 u32 token; 587 u32 type; 588 int (*get_token)(void *elem, void *object, u32 offset, u32 size); 589 u32 offset; 590 u32 size; 591 }; 592 593 static int get_token_u32(void *elem, void *object, u32 offset, u32 size) 594 { 595 struct snd_soc_tplg_vendor_value_elem *velem = elem; 596 u32 *val = (u32 *)((u8 *)object + offset); 597 598 *val = le32_to_cpu(velem->value); 599 return 0; 600 } 601 602 static int get_token_u16(void *elem, void *object, u32 offset, u32 size) 603 { 604 struct snd_soc_tplg_vendor_value_elem *velem = elem; 605 u16 *val = (u16 *)((u8 *)object + offset); 606 607 *val = (u16)le32_to_cpu(velem->value); 608 return 0; 609 } 610 611 static int get_token_comp_format(void *elem, void *object, u32 offset, u32 size) 612 { 613 struct snd_soc_tplg_vendor_string_elem *velem = elem; 614 u32 *val = (u32 *)((u8 *)object + offset); 615 616 *val = find_format(velem->string); 617 return 0; 618 } 619 620 static int get_token_dai_type(void *elem, void *object, u32 offset, u32 size) 621 { 622 struct snd_soc_tplg_vendor_string_elem *velem = elem; 623 u32 *val = (u32 *)((u8 *)object + offset); 624 625 *val = find_dai(velem->string); 626 return 0; 627 } 628 629 static int get_token_process_type(void *elem, void *object, u32 offset, 630 u32 size) 631 { 632 struct snd_soc_tplg_vendor_string_elem *velem = elem; 633 u32 *val = (u32 *)((u8 *)object + offset); 634 635 *val = find_process(velem->string); 636 return 0; 637 } 638 639 /* Buffers */ 640 static const struct sof_topology_token buffer_tokens[] = { 641 {SOF_TKN_BUF_SIZE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 642 offsetof(struct sof_ipc_buffer, size), 0}, 643 {SOF_TKN_BUF_CAPS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 644 offsetof(struct sof_ipc_buffer, caps), 0}, 645 }; 646 647 /* DAI */ 648 static const struct sof_topology_token dai_tokens[] = { 649 {SOF_TKN_DAI_TYPE, SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_dai_type, 650 offsetof(struct sof_ipc_comp_dai, type), 0}, 651 {SOF_TKN_DAI_INDEX, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 652 offsetof(struct sof_ipc_comp_dai, dai_index), 0}, 653 {SOF_TKN_DAI_DIRECTION, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 654 offsetof(struct sof_ipc_comp_dai, direction), 0}, 655 }; 656 657 /* BE DAI link */ 658 static const struct sof_topology_token dai_link_tokens[] = { 659 {SOF_TKN_DAI_TYPE, SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_dai_type, 660 offsetof(struct sof_ipc_dai_config, type), 0}, 661 {SOF_TKN_DAI_INDEX, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 662 offsetof(struct sof_ipc_dai_config, dai_index), 0}, 663 }; 664 665 /* scheduling */ 666 static const struct sof_topology_token sched_tokens[] = { 667 {SOF_TKN_SCHED_PERIOD, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 668 offsetof(struct sof_ipc_pipe_new, period), 0}, 669 {SOF_TKN_SCHED_PRIORITY, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 670 offsetof(struct sof_ipc_pipe_new, priority), 0}, 671 {SOF_TKN_SCHED_MIPS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 672 offsetof(struct sof_ipc_pipe_new, period_mips), 0}, 673 {SOF_TKN_SCHED_CORE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 674 offsetof(struct sof_ipc_pipe_new, core), 0}, 675 {SOF_TKN_SCHED_FRAMES, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 676 offsetof(struct sof_ipc_pipe_new, frames_per_sched), 0}, 677 {SOF_TKN_SCHED_TIME_DOMAIN, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 678 offsetof(struct sof_ipc_pipe_new, time_domain), 0}, 679 }; 680 681 /* volume */ 682 static const struct sof_topology_token volume_tokens[] = { 683 {SOF_TKN_VOLUME_RAMP_STEP_TYPE, SND_SOC_TPLG_TUPLE_TYPE_WORD, 684 get_token_u32, offsetof(struct sof_ipc_comp_volume, ramp), 0}, 685 {SOF_TKN_VOLUME_RAMP_STEP_MS, 686 SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 687 offsetof(struct sof_ipc_comp_volume, initial_ramp), 0}, 688 }; 689 690 /* SRC */ 691 static const struct sof_topology_token src_tokens[] = { 692 {SOF_TKN_SRC_RATE_IN, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 693 offsetof(struct sof_ipc_comp_src, source_rate), 0}, 694 {SOF_TKN_SRC_RATE_OUT, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 695 offsetof(struct sof_ipc_comp_src, sink_rate), 0}, 696 }; 697 698 /* Tone */ 699 static const struct sof_topology_token tone_tokens[] = { 700 }; 701 702 /* EFFECT */ 703 static const struct sof_topology_token process_tokens[] = { 704 {SOF_TKN_PROCESS_TYPE, SND_SOC_TPLG_TUPLE_TYPE_STRING, 705 get_token_process_type, 706 offsetof(struct sof_ipc_comp_process, type), 0}, 707 }; 708 709 /* PCM */ 710 static const struct sof_topology_token pcm_tokens[] = { 711 {SOF_TKN_PCM_DMAC_CONFIG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 712 offsetof(struct sof_ipc_comp_host, dmac_config), 0}, 713 }; 714 715 /* Generic components */ 716 static const struct sof_topology_token comp_tokens[] = { 717 {SOF_TKN_COMP_PERIOD_SINK_COUNT, 718 SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 719 offsetof(struct sof_ipc_comp_config, periods_sink), 0}, 720 {SOF_TKN_COMP_PERIOD_SOURCE_COUNT, 721 SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 722 offsetof(struct sof_ipc_comp_config, periods_source), 0}, 723 {SOF_TKN_COMP_FORMAT, 724 SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_comp_format, 725 offsetof(struct sof_ipc_comp_config, frame_fmt), 0}, 726 }; 727 728 /* SSP */ 729 static const struct sof_topology_token ssp_tokens[] = { 730 {SOF_TKN_INTEL_SSP_CLKS_CONTROL, 731 SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 732 offsetof(struct sof_ipc_dai_ssp_params, clks_control), 0}, 733 {SOF_TKN_INTEL_SSP_MCLK_ID, 734 SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16, 735 offsetof(struct sof_ipc_dai_ssp_params, mclk_id), 0}, 736 {SOF_TKN_INTEL_SSP_SAMPLE_BITS, SND_SOC_TPLG_TUPLE_TYPE_WORD, 737 get_token_u32, 738 offsetof(struct sof_ipc_dai_ssp_params, sample_valid_bits), 0}, 739 {SOF_TKN_INTEL_SSP_FRAME_PULSE_WIDTH, SND_SOC_TPLG_TUPLE_TYPE_SHORT, 740 get_token_u16, 741 offsetof(struct sof_ipc_dai_ssp_params, frame_pulse_width), 0}, 742 {SOF_TKN_INTEL_SSP_QUIRKS, SND_SOC_TPLG_TUPLE_TYPE_WORD, 743 get_token_u32, 744 offsetof(struct sof_ipc_dai_ssp_params, quirks), 0}, 745 {SOF_TKN_INTEL_SSP_TDM_PADDING_PER_SLOT, SND_SOC_TPLG_TUPLE_TYPE_BOOL, 746 get_token_u16, 747 offsetof(struct sof_ipc_dai_ssp_params, 748 tdm_per_slot_padding_flag), 0}, 749 750 }; 751 752 /* DMIC */ 753 static const struct sof_topology_token dmic_tokens[] = { 754 {SOF_TKN_INTEL_DMIC_DRIVER_VERSION, 755 SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 756 offsetof(struct sof_ipc_dai_dmic_params, driver_ipc_version), 757 0}, 758 {SOF_TKN_INTEL_DMIC_CLK_MIN, 759 SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 760 offsetof(struct sof_ipc_dai_dmic_params, pdmclk_min), 0}, 761 {SOF_TKN_INTEL_DMIC_CLK_MAX, 762 SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 763 offsetof(struct sof_ipc_dai_dmic_params, pdmclk_max), 0}, 764 {SOF_TKN_INTEL_DMIC_SAMPLE_RATE, 765 SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 766 offsetof(struct sof_ipc_dai_dmic_params, fifo_fs), 0}, 767 {SOF_TKN_INTEL_DMIC_DUTY_MIN, 768 SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16, 769 offsetof(struct sof_ipc_dai_dmic_params, duty_min), 0}, 770 {SOF_TKN_INTEL_DMIC_DUTY_MAX, 771 SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16, 772 offsetof(struct sof_ipc_dai_dmic_params, duty_max), 0}, 773 {SOF_TKN_INTEL_DMIC_NUM_PDM_ACTIVE, 774 SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 775 offsetof(struct sof_ipc_dai_dmic_params, 776 num_pdm_active), 0}, 777 {SOF_TKN_INTEL_DMIC_FIFO_WORD_LENGTH, 778 SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16, 779 offsetof(struct sof_ipc_dai_dmic_params, fifo_bits), 0}, 780 }; 781 782 /* 783 * DMIC PDM Tokens 784 * SOF_TKN_INTEL_DMIC_PDM_CTRL_ID should be the first token 785 * as it increments the index while parsing the array of pdm tokens 786 * and determines the correct offset 787 */ 788 static const struct sof_topology_token dmic_pdm_tokens[] = { 789 {SOF_TKN_INTEL_DMIC_PDM_CTRL_ID, 790 SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16, 791 offsetof(struct sof_ipc_dai_dmic_pdm_ctrl, id), 792 0}, 793 {SOF_TKN_INTEL_DMIC_PDM_MIC_A_Enable, 794 SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16, 795 offsetof(struct sof_ipc_dai_dmic_pdm_ctrl, enable_mic_a), 796 0}, 797 {SOF_TKN_INTEL_DMIC_PDM_MIC_B_Enable, 798 SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16, 799 offsetof(struct sof_ipc_dai_dmic_pdm_ctrl, enable_mic_b), 800 0}, 801 {SOF_TKN_INTEL_DMIC_PDM_POLARITY_A, 802 SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16, 803 offsetof(struct sof_ipc_dai_dmic_pdm_ctrl, polarity_mic_a), 804 0}, 805 {SOF_TKN_INTEL_DMIC_PDM_POLARITY_B, 806 SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16, 807 offsetof(struct sof_ipc_dai_dmic_pdm_ctrl, polarity_mic_b), 808 0}, 809 {SOF_TKN_INTEL_DMIC_PDM_CLK_EDGE, 810 SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16, 811 offsetof(struct sof_ipc_dai_dmic_pdm_ctrl, clk_edge), 812 0}, 813 {SOF_TKN_INTEL_DMIC_PDM_SKEW, 814 SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16, 815 offsetof(struct sof_ipc_dai_dmic_pdm_ctrl, skew), 816 0}, 817 }; 818 819 /* HDA */ 820 static const struct sof_topology_token hda_tokens[] = { 821 }; 822 823 static void sof_parse_uuid_tokens(struct snd_soc_component *scomp, 824 void *object, 825 const struct sof_topology_token *tokens, 826 int count, 827 struct snd_soc_tplg_vendor_array *array) 828 { 829 struct snd_soc_tplg_vendor_uuid_elem *elem; 830 int i, j; 831 832 /* parse element by element */ 833 for (i = 0; i < le32_to_cpu(array->num_elems); i++) { 834 elem = &array->uuid[i]; 835 836 /* search for token */ 837 for (j = 0; j < count; j++) { 838 /* match token type */ 839 if (tokens[j].type != SND_SOC_TPLG_TUPLE_TYPE_UUID) 840 continue; 841 842 /* match token id */ 843 if (tokens[j].token != le32_to_cpu(elem->token)) 844 continue; 845 846 /* matched - now load token */ 847 tokens[j].get_token(elem, object, tokens[j].offset, 848 tokens[j].size); 849 } 850 } 851 } 852 853 static void sof_parse_string_tokens(struct snd_soc_component *scomp, 854 void *object, 855 const struct sof_topology_token *tokens, 856 int count, 857 struct snd_soc_tplg_vendor_array *array) 858 { 859 struct snd_soc_tplg_vendor_string_elem *elem; 860 int i, j; 861 862 /* parse element by element */ 863 for (i = 0; i < le32_to_cpu(array->num_elems); i++) { 864 elem = &array->string[i]; 865 866 /* search for token */ 867 for (j = 0; j < count; j++) { 868 /* match token type */ 869 if (tokens[j].type != SND_SOC_TPLG_TUPLE_TYPE_STRING) 870 continue; 871 872 /* match token id */ 873 if (tokens[j].token != le32_to_cpu(elem->token)) 874 continue; 875 876 /* matched - now load token */ 877 tokens[j].get_token(elem, object, tokens[j].offset, 878 tokens[j].size); 879 } 880 } 881 } 882 883 static void sof_parse_word_tokens(struct snd_soc_component *scomp, 884 void *object, 885 const struct sof_topology_token *tokens, 886 int count, 887 struct snd_soc_tplg_vendor_array *array) 888 { 889 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 890 struct snd_soc_tplg_vendor_value_elem *elem; 891 size_t size = sizeof(struct sof_ipc_dai_dmic_pdm_ctrl); 892 int i, j; 893 u32 offset; 894 u32 *index = NULL; 895 896 /* parse element by element */ 897 for (i = 0; i < le32_to_cpu(array->num_elems); i++) { 898 elem = &array->value[i]; 899 900 /* search for token */ 901 for (j = 0; j < count; j++) { 902 /* match token type */ 903 if (!(tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_WORD || 904 tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_SHORT)) 905 continue; 906 907 /* match token id */ 908 if (tokens[j].token != le32_to_cpu(elem->token)) 909 continue; 910 911 /* pdm config array index */ 912 if (sdev->private) 913 index = sdev->private; 914 915 /* matched - determine offset */ 916 switch (tokens[j].token) { 917 case SOF_TKN_INTEL_DMIC_PDM_CTRL_ID: 918 919 /* inc number of pdm array index */ 920 if (index) 921 (*index)++; 922 /* fallthrough */ 923 case SOF_TKN_INTEL_DMIC_PDM_MIC_A_Enable: 924 case SOF_TKN_INTEL_DMIC_PDM_MIC_B_Enable: 925 case SOF_TKN_INTEL_DMIC_PDM_POLARITY_A: 926 case SOF_TKN_INTEL_DMIC_PDM_POLARITY_B: 927 case SOF_TKN_INTEL_DMIC_PDM_CLK_EDGE: 928 case SOF_TKN_INTEL_DMIC_PDM_SKEW: 929 930 /* check if array index is valid */ 931 if (!index || *index == 0) { 932 dev_err(sdev->dev, 933 "error: invalid array offset\n"); 934 continue; 935 } else { 936 /* offset within the pdm config array */ 937 offset = size * (*index - 1); 938 } 939 break; 940 default: 941 offset = 0; 942 break; 943 } 944 945 /* load token */ 946 tokens[j].get_token(elem, object, 947 offset + tokens[j].offset, 948 tokens[j].size); 949 } 950 } 951 } 952 953 static int sof_parse_tokens(struct snd_soc_component *scomp, 954 void *object, 955 const struct sof_topology_token *tokens, 956 int count, 957 struct snd_soc_tplg_vendor_array *array, 958 int priv_size) 959 { 960 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 961 int asize; 962 963 while (priv_size > 0) { 964 asize = le32_to_cpu(array->size); 965 966 /* validate asize */ 967 if (asize < 0) { /* FIXME: A zero-size array makes no sense */ 968 dev_err(sdev->dev, "error: invalid array size 0x%x\n", 969 asize); 970 return -EINVAL; 971 } 972 973 /* make sure there is enough data before parsing */ 974 priv_size -= asize; 975 if (priv_size < 0) { 976 dev_err(sdev->dev, "error: invalid array size 0x%x\n", 977 asize); 978 return -EINVAL; 979 } 980 981 /* call correct parser depending on type */ 982 switch (le32_to_cpu(array->type)) { 983 case SND_SOC_TPLG_TUPLE_TYPE_UUID: 984 sof_parse_uuid_tokens(scomp, object, tokens, count, 985 array); 986 break; 987 case SND_SOC_TPLG_TUPLE_TYPE_STRING: 988 sof_parse_string_tokens(scomp, object, tokens, count, 989 array); 990 break; 991 case SND_SOC_TPLG_TUPLE_TYPE_BOOL: 992 case SND_SOC_TPLG_TUPLE_TYPE_BYTE: 993 case SND_SOC_TPLG_TUPLE_TYPE_WORD: 994 case SND_SOC_TPLG_TUPLE_TYPE_SHORT: 995 sof_parse_word_tokens(scomp, object, tokens, count, 996 array); 997 break; 998 default: 999 dev_err(sdev->dev, "error: unknown token type %d\n", 1000 array->type); 1001 return -EINVAL; 1002 } 1003 1004 /* next array */ 1005 array = (struct snd_soc_tplg_vendor_array *)((u8 *)array 1006 + asize); 1007 } 1008 return 0; 1009 } 1010 1011 static void sof_dbg_comp_config(struct snd_soc_component *scomp, 1012 struct sof_ipc_comp_config *config) 1013 { 1014 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1015 1016 dev_dbg(sdev->dev, " config: periods snk %d src %d fmt %d\n", 1017 config->periods_sink, config->periods_source, 1018 config->frame_fmt); 1019 } 1020 1021 /* external kcontrol init - used for any driver specific init */ 1022 static int sof_control_load(struct snd_soc_component *scomp, int index, 1023 struct snd_kcontrol_new *kc, 1024 struct snd_soc_tplg_ctl_hdr *hdr) 1025 { 1026 struct soc_mixer_control *sm; 1027 struct soc_bytes_ext *sbe; 1028 struct soc_enum *se; 1029 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1030 struct snd_soc_dobj *dobj; 1031 struct snd_sof_control *scontrol; 1032 int ret = -EINVAL; 1033 1034 dev_dbg(sdev->dev, "tplg: load control type %d name : %s\n", 1035 hdr->type, hdr->name); 1036 1037 scontrol = kzalloc(sizeof(*scontrol), GFP_KERNEL); 1038 if (!scontrol) 1039 return -ENOMEM; 1040 1041 scontrol->sdev = sdev; 1042 1043 switch (le32_to_cpu(hdr->ops.info)) { 1044 case SND_SOC_TPLG_CTL_VOLSW: 1045 case SND_SOC_TPLG_CTL_VOLSW_SX: 1046 case SND_SOC_TPLG_CTL_VOLSW_XR_SX: 1047 sm = (struct soc_mixer_control *)kc->private_value; 1048 dobj = &sm->dobj; 1049 ret = sof_control_load_volume(scomp, scontrol, kc, hdr); 1050 break; 1051 case SND_SOC_TPLG_CTL_BYTES: 1052 sbe = (struct soc_bytes_ext *)kc->private_value; 1053 dobj = &sbe->dobj; 1054 ret = sof_control_load_bytes(scomp, scontrol, kc, hdr); 1055 break; 1056 case SND_SOC_TPLG_CTL_ENUM: 1057 case SND_SOC_TPLG_CTL_ENUM_VALUE: 1058 se = (struct soc_enum *)kc->private_value; 1059 dobj = &se->dobj; 1060 ret = sof_control_load_enum(scomp, scontrol, kc, hdr); 1061 break; 1062 case SND_SOC_TPLG_CTL_RANGE: 1063 case SND_SOC_TPLG_CTL_STROBE: 1064 case SND_SOC_TPLG_DAPM_CTL_VOLSW: 1065 case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE: 1066 case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT: 1067 case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE: 1068 case SND_SOC_TPLG_DAPM_CTL_PIN: 1069 default: 1070 dev_warn(sdev->dev, "control type not supported %d:%d:%d\n", 1071 hdr->ops.get, hdr->ops.put, hdr->ops.info); 1072 kfree(scontrol); 1073 return 0; 1074 } 1075 1076 dobj->private = scontrol; 1077 list_add(&scontrol->list, &sdev->kcontrol_list); 1078 return ret; 1079 } 1080 1081 static int sof_control_unload(struct snd_soc_component *scomp, 1082 struct snd_soc_dobj *dobj) 1083 { 1084 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1085 struct sof_ipc_free fcomp; 1086 struct snd_sof_control *scontrol = dobj->private; 1087 1088 dev_dbg(sdev->dev, "tplg: unload control name : %s\n", scomp->name); 1089 1090 fcomp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_FREE; 1091 fcomp.hdr.size = sizeof(fcomp); 1092 fcomp.id = scontrol->comp_id; 1093 1094 kfree(scontrol->control_data); 1095 list_del(&scontrol->list); 1096 kfree(scontrol); 1097 /* send IPC to the DSP */ 1098 return sof_ipc_tx_message(sdev->ipc, 1099 fcomp.hdr.cmd, &fcomp, sizeof(fcomp), 1100 NULL, 0); 1101 } 1102 1103 /* 1104 * DAI Topology 1105 */ 1106 1107 static int sof_connect_dai_widget(struct snd_soc_component *scomp, 1108 struct snd_soc_dapm_widget *w, 1109 struct snd_soc_tplg_dapm_widget *tw, 1110 struct snd_sof_dai *dai) 1111 { 1112 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1113 struct snd_soc_card *card = scomp->card; 1114 struct snd_soc_pcm_runtime *rtd; 1115 1116 list_for_each_entry(rtd, &card->rtd_list, list) { 1117 dev_vdbg(sdev->dev, "tplg: check widget: %s stream: %s dai stream: %s\n", 1118 w->name, w->sname, rtd->dai_link->stream_name); 1119 1120 if (!w->sname || !rtd->dai_link->stream_name) 1121 continue; 1122 1123 /* does stream match DAI link ? */ 1124 if (strcmp(w->sname, rtd->dai_link->stream_name)) 1125 continue; 1126 1127 switch (w->id) { 1128 case snd_soc_dapm_dai_out: 1129 rtd->cpu_dai->capture_widget = w; 1130 dai->name = rtd->dai_link->name; 1131 dev_dbg(sdev->dev, "tplg: connected widget %s -> DAI link %s\n", 1132 w->name, rtd->dai_link->name); 1133 break; 1134 case snd_soc_dapm_dai_in: 1135 rtd->cpu_dai->playback_widget = w; 1136 dai->name = rtd->dai_link->name; 1137 dev_dbg(sdev->dev, "tplg: connected widget %s -> DAI link %s\n", 1138 w->name, rtd->dai_link->name); 1139 break; 1140 default: 1141 break; 1142 } 1143 } 1144 1145 /* check we have a connection */ 1146 if (!dai->name) { 1147 dev_err(sdev->dev, "error: can't connect DAI %s stream %s\n", 1148 w->name, w->sname); 1149 return -EINVAL; 1150 } 1151 1152 return 0; 1153 } 1154 1155 static int sof_widget_load_dai(struct snd_soc_component *scomp, int index, 1156 struct snd_sof_widget *swidget, 1157 struct snd_soc_tplg_dapm_widget *tw, 1158 struct sof_ipc_comp_reply *r, 1159 struct snd_sof_dai *dai) 1160 { 1161 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1162 struct snd_soc_tplg_private *private = &tw->priv; 1163 struct sof_ipc_comp_dai comp_dai; 1164 int ret; 1165 1166 /* configure dai IPC message */ 1167 memset(&comp_dai, 0, sizeof(comp_dai)); 1168 comp_dai.comp.hdr.size = sizeof(comp_dai); 1169 comp_dai.comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; 1170 comp_dai.comp.id = swidget->comp_id; 1171 comp_dai.comp.type = SOF_COMP_DAI; 1172 comp_dai.comp.pipeline_id = index; 1173 comp_dai.config.hdr.size = sizeof(comp_dai.config); 1174 1175 ret = sof_parse_tokens(scomp, &comp_dai, dai_tokens, 1176 ARRAY_SIZE(dai_tokens), private->array, 1177 le32_to_cpu(private->size)); 1178 if (ret != 0) { 1179 dev_err(sdev->dev, "error: parse dai tokens failed %d\n", 1180 le32_to_cpu(private->size)); 1181 return ret; 1182 } 1183 1184 ret = sof_parse_tokens(scomp, &comp_dai.config, comp_tokens, 1185 ARRAY_SIZE(comp_tokens), private->array, 1186 le32_to_cpu(private->size)); 1187 if (ret != 0) { 1188 dev_err(sdev->dev, "error: parse dai.cfg tokens failed %d\n", 1189 private->size); 1190 return ret; 1191 } 1192 1193 dev_dbg(sdev->dev, "dai %s: type %d index %d\n", 1194 swidget->widget->name, comp_dai.type, comp_dai.dai_index); 1195 sof_dbg_comp_config(scomp, &comp_dai.config); 1196 1197 ret = sof_ipc_tx_message(sdev->ipc, comp_dai.comp.hdr.cmd, 1198 &comp_dai, sizeof(comp_dai), r, sizeof(*r)); 1199 1200 if (ret == 0 && dai) { 1201 dai->sdev = sdev; 1202 memcpy(&dai->comp_dai, &comp_dai, sizeof(comp_dai)); 1203 } 1204 1205 return ret; 1206 } 1207 1208 /* 1209 * Buffer topology 1210 */ 1211 1212 static int sof_widget_load_buffer(struct snd_soc_component *scomp, int index, 1213 struct snd_sof_widget *swidget, 1214 struct snd_soc_tplg_dapm_widget *tw, 1215 struct sof_ipc_comp_reply *r) 1216 { 1217 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1218 struct snd_soc_tplg_private *private = &tw->priv; 1219 struct sof_ipc_buffer *buffer; 1220 int ret; 1221 1222 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); 1223 if (!buffer) 1224 return -ENOMEM; 1225 1226 /* configure dai IPC message */ 1227 buffer->comp.hdr.size = sizeof(*buffer); 1228 buffer->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_BUFFER_NEW; 1229 buffer->comp.id = swidget->comp_id; 1230 buffer->comp.type = SOF_COMP_BUFFER; 1231 buffer->comp.pipeline_id = index; 1232 1233 ret = sof_parse_tokens(scomp, buffer, buffer_tokens, 1234 ARRAY_SIZE(buffer_tokens), private->array, 1235 le32_to_cpu(private->size)); 1236 if (ret != 0) { 1237 dev_err(sdev->dev, "error: parse buffer tokens failed %d\n", 1238 private->size); 1239 kfree(buffer); 1240 return ret; 1241 } 1242 1243 dev_dbg(sdev->dev, "buffer %s: size %d caps 0x%x\n", 1244 swidget->widget->name, buffer->size, buffer->caps); 1245 1246 swidget->private = buffer; 1247 1248 ret = sof_ipc_tx_message(sdev->ipc, buffer->comp.hdr.cmd, buffer, 1249 sizeof(*buffer), r, sizeof(*r)); 1250 if (ret < 0) { 1251 dev_err(sdev->dev, "error: buffer %s load failed\n", 1252 swidget->widget->name); 1253 kfree(buffer); 1254 } 1255 1256 return ret; 1257 } 1258 1259 /* bind PCM ID to host component ID */ 1260 static int spcm_bind(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, 1261 int dir) 1262 { 1263 struct snd_sof_widget *host_widget; 1264 1265 host_widget = snd_sof_find_swidget_sname(sdev, 1266 spcm->pcm.caps[dir].name, 1267 dir); 1268 if (!host_widget) { 1269 dev_err(sdev->dev, "can't find host comp to bind pcm\n"); 1270 return -EINVAL; 1271 } 1272 1273 spcm->stream[dir].comp_id = host_widget->comp_id; 1274 1275 return 0; 1276 } 1277 1278 /* 1279 * PCM Topology 1280 */ 1281 1282 static int sof_widget_load_pcm(struct snd_soc_component *scomp, int index, 1283 struct snd_sof_widget *swidget, 1284 enum sof_ipc_stream_direction dir, 1285 struct snd_soc_tplg_dapm_widget *tw, 1286 struct sof_ipc_comp_reply *r) 1287 { 1288 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1289 struct snd_soc_tplg_private *private = &tw->priv; 1290 struct sof_ipc_comp_host *host; 1291 int ret; 1292 1293 host = kzalloc(sizeof(*host), GFP_KERNEL); 1294 if (!host) 1295 return -ENOMEM; 1296 1297 /* configure host comp IPC message */ 1298 host->comp.hdr.size = sizeof(*host); 1299 host->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; 1300 host->comp.id = swidget->comp_id; 1301 host->comp.type = SOF_COMP_HOST; 1302 host->comp.pipeline_id = index; 1303 host->direction = dir; 1304 host->config.hdr.size = sizeof(host->config); 1305 1306 ret = sof_parse_tokens(scomp, host, pcm_tokens, 1307 ARRAY_SIZE(pcm_tokens), private->array, 1308 le32_to_cpu(private->size)); 1309 if (ret != 0) { 1310 dev_err(sdev->dev, "error: parse host tokens failed %d\n", 1311 private->size); 1312 goto err; 1313 } 1314 1315 ret = sof_parse_tokens(scomp, &host->config, comp_tokens, 1316 ARRAY_SIZE(comp_tokens), private->array, 1317 le32_to_cpu(private->size)); 1318 if (ret != 0) { 1319 dev_err(sdev->dev, "error: parse host.cfg tokens failed %d\n", 1320 le32_to_cpu(private->size)); 1321 goto err; 1322 } 1323 1324 dev_dbg(sdev->dev, "loaded host %s\n", swidget->widget->name); 1325 sof_dbg_comp_config(scomp, &host->config); 1326 1327 swidget->private = host; 1328 1329 ret = sof_ipc_tx_message(sdev->ipc, host->comp.hdr.cmd, host, 1330 sizeof(*host), r, sizeof(*r)); 1331 if (ret >= 0) 1332 return ret; 1333 err: 1334 kfree(host); 1335 return ret; 1336 } 1337 1338 /* 1339 * Pipeline Topology 1340 */ 1341 int sof_load_pipeline_ipc(struct snd_sof_dev *sdev, 1342 struct sof_ipc_pipe_new *pipeline, 1343 struct sof_ipc_comp_reply *r) 1344 { 1345 struct sof_ipc_pm_core_config pm_core_config; 1346 int ret; 1347 1348 ret = sof_ipc_tx_message(sdev->ipc, pipeline->hdr.cmd, pipeline, 1349 sizeof(*pipeline), r, sizeof(*r)); 1350 if (ret < 0) { 1351 dev_err(sdev->dev, "error: load pipeline ipc failure\n"); 1352 return ret; 1353 } 1354 1355 /* power up the core that this pipeline is scheduled on */ 1356 ret = snd_sof_dsp_core_power_up(sdev, 1 << pipeline->core); 1357 if (ret < 0) { 1358 dev_err(sdev->dev, "error: powering up pipeline schedule core %d\n", 1359 pipeline->core); 1360 return ret; 1361 } 1362 1363 /* update enabled cores mask */ 1364 sdev->enabled_cores_mask |= 1 << pipeline->core; 1365 1366 /* 1367 * Now notify DSP that the core that this pipeline is scheduled on 1368 * has been powered up 1369 */ 1370 memset(&pm_core_config, 0, sizeof(pm_core_config)); 1371 pm_core_config.enable_mask = sdev->enabled_cores_mask; 1372 1373 /* configure CORE_ENABLE ipc message */ 1374 pm_core_config.hdr.size = sizeof(pm_core_config); 1375 pm_core_config.hdr.cmd = SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_CORE_ENABLE; 1376 1377 /* send ipc */ 1378 ret = sof_ipc_tx_message(sdev->ipc, pm_core_config.hdr.cmd, 1379 &pm_core_config, sizeof(pm_core_config), 1380 &pm_core_config, sizeof(pm_core_config)); 1381 if (ret < 0) 1382 dev_err(sdev->dev, "error: core enable ipc failure\n"); 1383 1384 return ret; 1385 } 1386 1387 static int sof_widget_load_pipeline(struct snd_soc_component *scomp, 1388 int index, struct snd_sof_widget *swidget, 1389 struct snd_soc_tplg_dapm_widget *tw, 1390 struct sof_ipc_comp_reply *r) 1391 { 1392 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1393 struct snd_soc_tplg_private *private = &tw->priv; 1394 struct sof_ipc_pipe_new *pipeline; 1395 struct snd_sof_widget *comp_swidget; 1396 int ret; 1397 1398 pipeline = kzalloc(sizeof(*pipeline), GFP_KERNEL); 1399 if (!pipeline) 1400 return -ENOMEM; 1401 1402 /* configure dai IPC message */ 1403 pipeline->hdr.size = sizeof(*pipeline); 1404 pipeline->hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_PIPE_NEW; 1405 pipeline->pipeline_id = index; 1406 pipeline->comp_id = swidget->comp_id; 1407 1408 /* component at start of pipeline is our stream id */ 1409 comp_swidget = snd_sof_find_swidget(sdev, tw->sname); 1410 if (!comp_swidget) { 1411 dev_err(sdev->dev, "error: widget %s refers to non existent widget %s\n", 1412 tw->name, tw->sname); 1413 ret = -EINVAL; 1414 goto err; 1415 } 1416 1417 pipeline->sched_id = comp_swidget->comp_id; 1418 1419 dev_dbg(sdev->dev, "tplg: pipeline id %d comp %d scheduling comp id %d\n", 1420 pipeline->pipeline_id, pipeline->comp_id, pipeline->sched_id); 1421 1422 ret = sof_parse_tokens(scomp, pipeline, sched_tokens, 1423 ARRAY_SIZE(sched_tokens), private->array, 1424 le32_to_cpu(private->size)); 1425 if (ret != 0) { 1426 dev_err(sdev->dev, "error: parse pipeline tokens failed %d\n", 1427 private->size); 1428 goto err; 1429 } 1430 1431 dev_dbg(sdev->dev, "pipeline %s: period %d pri %d mips %d core %d frames %d\n", 1432 swidget->widget->name, pipeline->period, pipeline->priority, 1433 pipeline->period_mips, pipeline->core, pipeline->frames_per_sched); 1434 1435 swidget->private = pipeline; 1436 1437 /* send ipc's to create pipeline comp and power up schedule core */ 1438 ret = sof_load_pipeline_ipc(sdev, pipeline, r); 1439 if (ret >= 0) 1440 return ret; 1441 err: 1442 kfree(pipeline); 1443 return ret; 1444 } 1445 1446 /* 1447 * Mixer topology 1448 */ 1449 1450 static int sof_widget_load_mixer(struct snd_soc_component *scomp, int index, 1451 struct snd_sof_widget *swidget, 1452 struct snd_soc_tplg_dapm_widget *tw, 1453 struct sof_ipc_comp_reply *r) 1454 { 1455 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1456 struct snd_soc_tplg_private *private = &tw->priv; 1457 struct sof_ipc_comp_mixer *mixer; 1458 int ret; 1459 1460 mixer = kzalloc(sizeof(*mixer), GFP_KERNEL); 1461 if (!mixer) 1462 return -ENOMEM; 1463 1464 /* configure mixer IPC message */ 1465 mixer->comp.hdr.size = sizeof(*mixer); 1466 mixer->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; 1467 mixer->comp.id = swidget->comp_id; 1468 mixer->comp.type = SOF_COMP_MIXER; 1469 mixer->comp.pipeline_id = index; 1470 mixer->config.hdr.size = sizeof(mixer->config); 1471 1472 ret = sof_parse_tokens(scomp, &mixer->config, comp_tokens, 1473 ARRAY_SIZE(comp_tokens), private->array, 1474 le32_to_cpu(private->size)); 1475 if (ret != 0) { 1476 dev_err(sdev->dev, "error: parse mixer.cfg tokens failed %d\n", 1477 private->size); 1478 kfree(mixer); 1479 return ret; 1480 } 1481 1482 sof_dbg_comp_config(scomp, &mixer->config); 1483 1484 swidget->private = mixer; 1485 1486 ret = sof_ipc_tx_message(sdev->ipc, mixer->comp.hdr.cmd, mixer, 1487 sizeof(*mixer), r, sizeof(*r)); 1488 if (ret < 0) 1489 kfree(mixer); 1490 1491 return ret; 1492 } 1493 1494 /* 1495 * Mux topology 1496 */ 1497 static int sof_widget_load_mux(struct snd_soc_component *scomp, int index, 1498 struct snd_sof_widget *swidget, 1499 struct snd_soc_tplg_dapm_widget *tw, 1500 struct sof_ipc_comp_reply *r) 1501 { 1502 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1503 struct snd_soc_tplg_private *private = &tw->priv; 1504 struct sof_ipc_comp_mux *mux; 1505 int ret; 1506 1507 mux = kzalloc(sizeof(*mux), GFP_KERNEL); 1508 if (!mux) 1509 return -ENOMEM; 1510 1511 /* configure mux IPC message */ 1512 mux->comp.hdr.size = sizeof(*mux); 1513 mux->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; 1514 mux->comp.id = swidget->comp_id; 1515 mux->comp.type = SOF_COMP_MUX; 1516 mux->comp.pipeline_id = index; 1517 mux->config.hdr.size = sizeof(mux->config); 1518 1519 ret = sof_parse_tokens(scomp, &mux->config, comp_tokens, 1520 ARRAY_SIZE(comp_tokens), private->array, 1521 le32_to_cpu(private->size)); 1522 if (ret != 0) { 1523 dev_err(sdev->dev, "error: parse mux.cfg tokens failed %d\n", 1524 private->size); 1525 kfree(mux); 1526 return ret; 1527 } 1528 1529 sof_dbg_comp_config(scomp, &mux->config); 1530 1531 swidget->private = mux; 1532 1533 ret = sof_ipc_tx_message(sdev->ipc, mux->comp.hdr.cmd, mux, 1534 sizeof(*mux), r, sizeof(*r)); 1535 if (ret < 0) 1536 kfree(mux); 1537 1538 return ret; 1539 } 1540 1541 /* 1542 * PGA Topology 1543 */ 1544 1545 static int sof_widget_load_pga(struct snd_soc_component *scomp, int index, 1546 struct snd_sof_widget *swidget, 1547 struct snd_soc_tplg_dapm_widget *tw, 1548 struct sof_ipc_comp_reply *r) 1549 { 1550 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1551 struct snd_soc_tplg_private *private = &tw->priv; 1552 struct sof_ipc_comp_volume *volume; 1553 int ret; 1554 1555 volume = kzalloc(sizeof(*volume), GFP_KERNEL); 1556 if (!volume) 1557 return -ENOMEM; 1558 1559 if (le32_to_cpu(tw->num_kcontrols) != 1) { 1560 dev_err(sdev->dev, "error: invalid kcontrol count %d for volume\n", 1561 tw->num_kcontrols); 1562 ret = -EINVAL; 1563 goto err; 1564 } 1565 1566 /* configure volume IPC message */ 1567 volume->comp.hdr.size = sizeof(*volume); 1568 volume->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; 1569 volume->comp.id = swidget->comp_id; 1570 volume->comp.type = SOF_COMP_VOLUME; 1571 volume->comp.pipeline_id = index; 1572 volume->config.hdr.size = sizeof(volume->config); 1573 1574 ret = sof_parse_tokens(scomp, volume, volume_tokens, 1575 ARRAY_SIZE(volume_tokens), private->array, 1576 le32_to_cpu(private->size)); 1577 if (ret != 0) { 1578 dev_err(sdev->dev, "error: parse volume tokens failed %d\n", 1579 private->size); 1580 goto err; 1581 } 1582 ret = sof_parse_tokens(scomp, &volume->config, comp_tokens, 1583 ARRAY_SIZE(comp_tokens), private->array, 1584 le32_to_cpu(private->size)); 1585 if (ret != 0) { 1586 dev_err(sdev->dev, "error: parse volume.cfg tokens failed %d\n", 1587 le32_to_cpu(private->size)); 1588 goto err; 1589 } 1590 1591 sof_dbg_comp_config(scomp, &volume->config); 1592 1593 swidget->private = volume; 1594 1595 ret = sof_ipc_tx_message(sdev->ipc, volume->comp.hdr.cmd, volume, 1596 sizeof(*volume), r, sizeof(*r)); 1597 if (ret >= 0) 1598 return ret; 1599 err: 1600 kfree(volume); 1601 return ret; 1602 } 1603 1604 /* 1605 * SRC Topology 1606 */ 1607 1608 static int sof_widget_load_src(struct snd_soc_component *scomp, int index, 1609 struct snd_sof_widget *swidget, 1610 struct snd_soc_tplg_dapm_widget *tw, 1611 struct sof_ipc_comp_reply *r) 1612 { 1613 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1614 struct snd_soc_tplg_private *private = &tw->priv; 1615 struct sof_ipc_comp_src *src; 1616 int ret; 1617 1618 src = kzalloc(sizeof(*src), GFP_KERNEL); 1619 if (!src) 1620 return -ENOMEM; 1621 1622 /* configure src IPC message */ 1623 src->comp.hdr.size = sizeof(*src); 1624 src->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; 1625 src->comp.id = swidget->comp_id; 1626 src->comp.type = SOF_COMP_SRC; 1627 src->comp.pipeline_id = index; 1628 src->config.hdr.size = sizeof(src->config); 1629 1630 ret = sof_parse_tokens(scomp, src, src_tokens, 1631 ARRAY_SIZE(src_tokens), private->array, 1632 le32_to_cpu(private->size)); 1633 if (ret != 0) { 1634 dev_err(sdev->dev, "error: parse src tokens failed %d\n", 1635 private->size); 1636 goto err; 1637 } 1638 1639 ret = sof_parse_tokens(scomp, &src->config, comp_tokens, 1640 ARRAY_SIZE(comp_tokens), private->array, 1641 le32_to_cpu(private->size)); 1642 if (ret != 0) { 1643 dev_err(sdev->dev, "error: parse src.cfg tokens failed %d\n", 1644 le32_to_cpu(private->size)); 1645 goto err; 1646 } 1647 1648 dev_dbg(sdev->dev, "src %s: source rate %d sink rate %d\n", 1649 swidget->widget->name, src->source_rate, src->sink_rate); 1650 sof_dbg_comp_config(scomp, &src->config); 1651 1652 swidget->private = src; 1653 1654 ret = sof_ipc_tx_message(sdev->ipc, src->comp.hdr.cmd, src, 1655 sizeof(*src), r, sizeof(*r)); 1656 if (ret >= 0) 1657 return ret; 1658 err: 1659 kfree(src); 1660 return ret; 1661 } 1662 1663 /* 1664 * Signal Generator Topology 1665 */ 1666 1667 static int sof_widget_load_siggen(struct snd_soc_component *scomp, int index, 1668 struct snd_sof_widget *swidget, 1669 struct snd_soc_tplg_dapm_widget *tw, 1670 struct sof_ipc_comp_reply *r) 1671 { 1672 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1673 struct snd_soc_tplg_private *private = &tw->priv; 1674 struct sof_ipc_comp_tone *tone; 1675 int ret; 1676 1677 tone = kzalloc(sizeof(*tone), GFP_KERNEL); 1678 if (!tone) 1679 return -ENOMEM; 1680 1681 /* configure siggen IPC message */ 1682 tone->comp.hdr.size = sizeof(*tone); 1683 tone->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; 1684 tone->comp.id = swidget->comp_id; 1685 tone->comp.type = SOF_COMP_TONE; 1686 tone->comp.pipeline_id = index; 1687 tone->config.hdr.size = sizeof(tone->config); 1688 1689 ret = sof_parse_tokens(scomp, tone, tone_tokens, 1690 ARRAY_SIZE(tone_tokens), private->array, 1691 le32_to_cpu(private->size)); 1692 if (ret != 0) { 1693 dev_err(sdev->dev, "error: parse tone tokens failed %d\n", 1694 le32_to_cpu(private->size)); 1695 goto err; 1696 } 1697 1698 ret = sof_parse_tokens(scomp, &tone->config, comp_tokens, 1699 ARRAY_SIZE(comp_tokens), private->array, 1700 le32_to_cpu(private->size)); 1701 if (ret != 0) { 1702 dev_err(sdev->dev, "error: parse tone.cfg tokens failed %d\n", 1703 le32_to_cpu(private->size)); 1704 goto err; 1705 } 1706 1707 dev_dbg(sdev->dev, "tone %s: frequency %d amplitude %d\n", 1708 swidget->widget->name, tone->frequency, tone->amplitude); 1709 sof_dbg_comp_config(scomp, &tone->config); 1710 1711 swidget->private = tone; 1712 1713 ret = sof_ipc_tx_message(sdev->ipc, tone->comp.hdr.cmd, tone, 1714 sizeof(*tone), r, sizeof(*r)); 1715 if (ret >= 0) 1716 return ret; 1717 err: 1718 kfree(tone); 1719 return ret; 1720 } 1721 1722 static int sof_process_load(struct snd_soc_component *scomp, int index, 1723 struct snd_sof_widget *swidget, 1724 struct snd_soc_tplg_dapm_widget *tw, 1725 struct sof_ipc_comp_reply *r, 1726 int type) 1727 { 1728 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1729 struct snd_soc_tplg_private *private = &tw->priv; 1730 struct snd_soc_dapm_widget *widget = swidget->widget; 1731 const struct snd_kcontrol_new *kc; 1732 struct soc_bytes_ext *sbe; 1733 struct soc_mixer_control *sm; 1734 struct soc_enum *se; 1735 struct snd_sof_control *scontrol = NULL; 1736 struct sof_abi_hdr *pdata = NULL; 1737 struct sof_ipc_comp_process *process; 1738 size_t ipc_size, ipc_data_size = 0; 1739 int ret, i, offset = 0; 1740 1741 if (type == SOF_COMP_NONE) { 1742 dev_err(sdev->dev, "error: invalid process comp type %d\n", 1743 type); 1744 return -EINVAL; 1745 } 1746 1747 /* 1748 * get possible component controls - get size of all pdata, 1749 * then memcpy with headers 1750 */ 1751 for (i = 0; i < widget->num_kcontrols; i++) { 1752 1753 kc = &widget->kcontrol_news[i]; 1754 1755 switch (widget->dobj.widget.kcontrol_type) { 1756 case SND_SOC_TPLG_TYPE_MIXER: 1757 sm = (struct soc_mixer_control *)kc->private_value; 1758 scontrol = sm->dobj.private; 1759 break; 1760 case SND_SOC_TPLG_TYPE_BYTES: 1761 sbe = (struct soc_bytes_ext *)kc->private_value; 1762 scontrol = sbe->dobj.private; 1763 break; 1764 case SND_SOC_TPLG_TYPE_ENUM: 1765 se = (struct soc_enum *)kc->private_value; 1766 scontrol = se->dobj.private; 1767 break; 1768 default: 1769 dev_err(sdev->dev, "error: unknown kcontrol type %d in widget %s\n", 1770 widget->dobj.widget.kcontrol_type, 1771 widget->name); 1772 return -EINVAL; 1773 } 1774 1775 if (!scontrol) { 1776 dev_err(sdev->dev, "error: no scontrol for widget %s\n", 1777 widget->name); 1778 return -EINVAL; 1779 } 1780 1781 /* don't include if no private data */ 1782 pdata = scontrol->control_data->data; 1783 if (!pdata) 1784 continue; 1785 1786 /* make sure data is valid - data can be updated at runtime */ 1787 if (pdata->magic != SOF_ABI_MAGIC) 1788 continue; 1789 1790 ipc_data_size += pdata->size; 1791 } 1792 1793 ipc_size = sizeof(struct sof_ipc_comp_process) + 1794 le32_to_cpu(private->size) + 1795 ipc_data_size; 1796 1797 process = kzalloc(ipc_size, GFP_KERNEL); 1798 if (!process) 1799 return -ENOMEM; 1800 1801 /* configure iir IPC message */ 1802 process->comp.hdr.size = ipc_size; 1803 process->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; 1804 process->comp.id = swidget->comp_id; 1805 process->comp.type = type; 1806 process->comp.pipeline_id = index; 1807 process->config.hdr.size = sizeof(process->config); 1808 1809 ret = sof_parse_tokens(scomp, &process->config, comp_tokens, 1810 ARRAY_SIZE(comp_tokens), private->array, 1811 le32_to_cpu(private->size)); 1812 if (ret != 0) { 1813 dev_err(sdev->dev, "error: parse process.cfg tokens failed %d\n", 1814 le32_to_cpu(private->size)); 1815 goto err; 1816 } 1817 1818 sof_dbg_comp_config(scomp, &process->config); 1819 1820 /* 1821 * found private data in control, so copy it. 1822 * get possible component controls - get size of all pdata, 1823 * then memcpy with headers 1824 */ 1825 for (i = 0; i < widget->num_kcontrols; i++) { 1826 kc = &widget->kcontrol_news[i]; 1827 1828 switch (widget->dobj.widget.kcontrol_type) { 1829 case SND_SOC_TPLG_TYPE_MIXER: 1830 sm = (struct soc_mixer_control *)kc->private_value; 1831 scontrol = sm->dobj.private; 1832 break; 1833 case SND_SOC_TPLG_TYPE_BYTES: 1834 sbe = (struct soc_bytes_ext *)kc->private_value; 1835 scontrol = sbe->dobj.private; 1836 break; 1837 case SND_SOC_TPLG_TYPE_ENUM: 1838 se = (struct soc_enum *)kc->private_value; 1839 scontrol = se->dobj.private; 1840 break; 1841 default: 1842 dev_err(sdev->dev, "error: unknown kcontrol type %d in widget %s\n", 1843 widget->dobj.widget.kcontrol_type, 1844 widget->name); 1845 return -EINVAL; 1846 } 1847 1848 /* don't include if no private data */ 1849 pdata = scontrol->control_data->data; 1850 if (!pdata) 1851 continue; 1852 1853 /* make sure data is valid - data can be updated at runtime */ 1854 if (pdata->magic != SOF_ABI_MAGIC) 1855 continue; 1856 1857 memcpy(&process->data + offset, pdata->data, pdata->size); 1858 offset += pdata->size; 1859 } 1860 1861 process->size = ipc_data_size; 1862 swidget->private = process; 1863 1864 ret = sof_ipc_tx_message(sdev->ipc, process->comp.hdr.cmd, process, 1865 ipc_size, r, sizeof(*r)); 1866 if (ret >= 0) 1867 return ret; 1868 err: 1869 kfree(process); 1870 return ret; 1871 } 1872 1873 /* 1874 * Processing Component Topology - can be "effect", "codec", or general 1875 * "processing". 1876 */ 1877 1878 static int sof_widget_load_process(struct snd_soc_component *scomp, int index, 1879 struct snd_sof_widget *swidget, 1880 struct snd_soc_tplg_dapm_widget *tw, 1881 struct sof_ipc_comp_reply *r) 1882 { 1883 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1884 struct snd_soc_tplg_private *private = &tw->priv; 1885 struct sof_ipc_comp_process config; 1886 int ret; 1887 1888 /* check we have some tokens - we need at least process type */ 1889 if (le32_to_cpu(private->size) == 0) { 1890 dev_err(sdev->dev, "error: process tokens not found\n"); 1891 return -EINVAL; 1892 } 1893 1894 memset(&config, 0, sizeof(config)); 1895 1896 /* get the process token */ 1897 ret = sof_parse_tokens(scomp, &config, process_tokens, 1898 ARRAY_SIZE(process_tokens), private->array, 1899 le32_to_cpu(private->size)); 1900 if (ret != 0) { 1901 dev_err(sdev->dev, "error: parse process tokens failed %d\n", 1902 le32_to_cpu(private->size)); 1903 return ret; 1904 } 1905 1906 /* now load process specific data and send IPC */ 1907 ret = sof_process_load(scomp, index, swidget, tw, r, 1908 find_process_comp_type(config.type)); 1909 if (ret < 0) { 1910 dev_err(sdev->dev, "error: process loading failed\n"); 1911 return ret; 1912 } 1913 1914 return 0; 1915 } 1916 1917 static int sof_widget_bind_event(struct snd_sof_dev *sdev, 1918 struct snd_sof_widget *swidget, 1919 u16 event_type) 1920 { 1921 struct sof_ipc_comp *ipc_comp; 1922 1923 /* validate widget event type */ 1924 switch (event_type) { 1925 case SOF_KEYWORD_DETECT_DAPM_EVENT: 1926 /* only KEYWORD_DETECT comps should handle this */ 1927 if (swidget->id != snd_soc_dapm_effect) 1928 break; 1929 1930 ipc_comp = swidget->private; 1931 if (ipc_comp && ipc_comp->type != SOF_COMP_KEYWORD_DETECT) 1932 break; 1933 1934 /* bind event to keyword detect comp */ 1935 return snd_soc_tplg_widget_bind_event(swidget->widget, 1936 sof_kwd_events, 1937 ARRAY_SIZE(sof_kwd_events), 1938 event_type); 1939 default: 1940 break; 1941 } 1942 1943 dev_err(sdev->dev, 1944 "error: invalid event type %d for widget %s\n", 1945 event_type, swidget->widget->name); 1946 return -EINVAL; 1947 } 1948 1949 /* external widget init - used for any driver specific init */ 1950 static int sof_widget_ready(struct snd_soc_component *scomp, int index, 1951 struct snd_soc_dapm_widget *w, 1952 struct snd_soc_tplg_dapm_widget *tw) 1953 { 1954 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1955 struct snd_sof_widget *swidget; 1956 struct snd_sof_dai *dai; 1957 struct sof_ipc_comp_reply reply; 1958 struct snd_sof_control *scontrol; 1959 int ret = 0; 1960 1961 swidget = kzalloc(sizeof(*swidget), GFP_KERNEL); 1962 if (!swidget) 1963 return -ENOMEM; 1964 1965 swidget->sdev = sdev; 1966 swidget->widget = w; 1967 swidget->comp_id = sdev->next_comp_id++; 1968 swidget->complete = 0; 1969 swidget->id = w->id; 1970 swidget->pipeline_id = index; 1971 swidget->private = NULL; 1972 memset(&reply, 0, sizeof(reply)); 1973 1974 dev_dbg(sdev->dev, "tplg: ready widget id %d pipe %d type %d name : %s stream %s\n", 1975 swidget->comp_id, index, swidget->id, tw->name, 1976 strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0 1977 ? tw->sname : "none"); 1978 1979 /* handle any special case widgets */ 1980 switch (w->id) { 1981 case snd_soc_dapm_dai_in: 1982 case snd_soc_dapm_dai_out: 1983 dai = kzalloc(sizeof(*dai), GFP_KERNEL); 1984 if (!dai) { 1985 kfree(swidget); 1986 return -ENOMEM; 1987 } 1988 1989 ret = sof_widget_load_dai(scomp, index, swidget, tw, &reply, 1990 dai); 1991 if (ret == 0) { 1992 sof_connect_dai_widget(scomp, w, tw, dai); 1993 list_add(&dai->list, &sdev->dai_list); 1994 swidget->private = dai; 1995 } else { 1996 kfree(dai); 1997 } 1998 break; 1999 case snd_soc_dapm_mixer: 2000 ret = sof_widget_load_mixer(scomp, index, swidget, tw, &reply); 2001 break; 2002 case snd_soc_dapm_pga: 2003 ret = sof_widget_load_pga(scomp, index, swidget, tw, &reply); 2004 /* Find scontrol for this pga and set readback offset*/ 2005 list_for_each_entry(scontrol, &sdev->kcontrol_list, list) { 2006 if (scontrol->comp_id == swidget->comp_id) { 2007 scontrol->readback_offset = reply.offset; 2008 break; 2009 } 2010 } 2011 break; 2012 case snd_soc_dapm_buffer: 2013 ret = sof_widget_load_buffer(scomp, index, swidget, tw, &reply); 2014 break; 2015 case snd_soc_dapm_scheduler: 2016 ret = sof_widget_load_pipeline(scomp, index, swidget, tw, 2017 &reply); 2018 break; 2019 case snd_soc_dapm_aif_out: 2020 ret = sof_widget_load_pcm(scomp, index, swidget, 2021 SOF_IPC_STREAM_CAPTURE, tw, &reply); 2022 break; 2023 case snd_soc_dapm_aif_in: 2024 ret = sof_widget_load_pcm(scomp, index, swidget, 2025 SOF_IPC_STREAM_PLAYBACK, tw, &reply); 2026 break; 2027 case snd_soc_dapm_src: 2028 ret = sof_widget_load_src(scomp, index, swidget, tw, &reply); 2029 break; 2030 case snd_soc_dapm_siggen: 2031 ret = sof_widget_load_siggen(scomp, index, swidget, tw, &reply); 2032 break; 2033 case snd_soc_dapm_effect: 2034 ret = sof_widget_load_process(scomp, index, swidget, tw, 2035 &reply); 2036 break; 2037 case snd_soc_dapm_mux: 2038 case snd_soc_dapm_demux: 2039 ret = sof_widget_load_mux(scomp, index, swidget, tw, &reply); 2040 break; 2041 case snd_soc_dapm_switch: 2042 case snd_soc_dapm_dai_link: 2043 case snd_soc_dapm_kcontrol: 2044 default: 2045 dev_warn(sdev->dev, "warning: widget type %d name %s not handled\n", 2046 swidget->id, tw->name); 2047 break; 2048 } 2049 2050 /* check IPC reply */ 2051 if (ret < 0 || reply.rhdr.error < 0) { 2052 dev_err(sdev->dev, 2053 "error: DSP failed to add widget id %d type %d name : %s stream %s reply %d\n", 2054 tw->shift, swidget->id, tw->name, 2055 strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0 2056 ? tw->sname : "none", reply.rhdr.error); 2057 kfree(swidget); 2058 return ret; 2059 } 2060 2061 /* bind widget to external event */ 2062 if (tw->event_type) { 2063 ret = sof_widget_bind_event(sdev, swidget, 2064 le16_to_cpu(tw->event_type)); 2065 if (ret) { 2066 dev_err(sdev->dev, "error: widget event binding failed\n"); 2067 kfree(swidget->private); 2068 kfree(swidget); 2069 return ret; 2070 } 2071 } 2072 2073 w->dobj.private = swidget; 2074 list_add(&swidget->list, &sdev->widget_list); 2075 return ret; 2076 } 2077 2078 static int sof_route_unload(struct snd_soc_component *scomp, 2079 struct snd_soc_dobj *dobj) 2080 { 2081 struct snd_sof_route *sroute; 2082 2083 sroute = dobj->private; 2084 if (!sroute) 2085 return 0; 2086 2087 /* free sroute and its private data */ 2088 kfree(sroute->private); 2089 list_del(&sroute->list); 2090 kfree(sroute); 2091 2092 return 0; 2093 } 2094 2095 static int sof_widget_unload(struct snd_soc_component *scomp, 2096 struct snd_soc_dobj *dobj) 2097 { 2098 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 2099 const struct snd_kcontrol_new *kc; 2100 struct snd_soc_dapm_widget *widget; 2101 struct sof_ipc_pipe_new *pipeline; 2102 struct snd_sof_control *scontrol; 2103 struct snd_sof_widget *swidget; 2104 struct soc_mixer_control *sm; 2105 struct soc_bytes_ext *sbe; 2106 struct snd_sof_dai *dai; 2107 struct soc_enum *se; 2108 int ret = 0; 2109 int i; 2110 2111 swidget = dobj->private; 2112 if (!swidget) 2113 return 0; 2114 2115 widget = swidget->widget; 2116 2117 switch (swidget->id) { 2118 case snd_soc_dapm_dai_in: 2119 case snd_soc_dapm_dai_out: 2120 dai = swidget->private; 2121 2122 if (dai) { 2123 /* free dai config */ 2124 kfree(dai->dai_config); 2125 list_del(&dai->list); 2126 } 2127 break; 2128 case snd_soc_dapm_scheduler: 2129 2130 /* power down the pipeline schedule core */ 2131 pipeline = swidget->private; 2132 ret = snd_sof_dsp_core_power_down(sdev, 1 << pipeline->core); 2133 if (ret < 0) 2134 dev_err(sdev->dev, "error: powering down pipeline schedule core %d\n", 2135 pipeline->core); 2136 2137 /* update enabled cores mask */ 2138 sdev->enabled_cores_mask &= ~(1 << pipeline->core); 2139 2140 break; 2141 default: 2142 break; 2143 } 2144 for (i = 0; i < widget->num_kcontrols; i++) { 2145 kc = &widget->kcontrol_news[i]; 2146 switch (dobj->widget.kcontrol_type) { 2147 case SND_SOC_TPLG_TYPE_MIXER: 2148 sm = (struct soc_mixer_control *)kc->private_value; 2149 scontrol = sm->dobj.private; 2150 if (sm->max > 1) 2151 kfree(scontrol->volume_table); 2152 break; 2153 case SND_SOC_TPLG_TYPE_ENUM: 2154 se = (struct soc_enum *)kc->private_value; 2155 scontrol = se->dobj.private; 2156 break; 2157 case SND_SOC_TPLG_TYPE_BYTES: 2158 sbe = (struct soc_bytes_ext *)kc->private_value; 2159 scontrol = sbe->dobj.private; 2160 break; 2161 default: 2162 dev_warn(sdev->dev, "unsupported kcontrol_type\n"); 2163 goto out; 2164 } 2165 kfree(scontrol->control_data); 2166 list_del(&scontrol->list); 2167 kfree(scontrol); 2168 } 2169 2170 out: 2171 /* free private value */ 2172 kfree(swidget->private); 2173 2174 /* remove and free swidget object */ 2175 list_del(&swidget->list); 2176 kfree(swidget); 2177 2178 return ret; 2179 } 2180 2181 /* 2182 * DAI HW configuration. 2183 */ 2184 2185 /* FE DAI - used for any driver specific init */ 2186 static int sof_dai_load(struct snd_soc_component *scomp, int index, 2187 struct snd_soc_dai_driver *dai_drv, 2188 struct snd_soc_tplg_pcm *pcm, struct snd_soc_dai *dai) 2189 { 2190 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 2191 struct snd_soc_tplg_stream_caps *caps; 2192 struct snd_sof_pcm *spcm; 2193 int stream = SNDRV_PCM_STREAM_PLAYBACK; 2194 int ret = 0; 2195 2196 /* nothing to do for BEs atm */ 2197 if (!pcm) 2198 return 0; 2199 2200 spcm = kzalloc(sizeof(*spcm), GFP_KERNEL); 2201 if (!spcm) 2202 return -ENOMEM; 2203 2204 spcm->sdev = sdev; 2205 spcm->stream[SNDRV_PCM_STREAM_PLAYBACK].comp_id = COMP_ID_UNASSIGNED; 2206 spcm->stream[SNDRV_PCM_STREAM_CAPTURE].comp_id = COMP_ID_UNASSIGNED; 2207 2208 if (pcm) { 2209 spcm->pcm = *pcm; 2210 dev_dbg(sdev->dev, "tplg: load pcm %s\n", pcm->dai_name); 2211 } 2212 dai_drv->dobj.private = spcm; 2213 list_add(&spcm->list, &sdev->pcm_list); 2214 2215 /* do we need to allocate playback PCM DMA pages */ 2216 if (!spcm->pcm.playback) 2217 goto capture; 2218 2219 caps = &spcm->pcm.caps[stream]; 2220 2221 /* allocate playback page table buffer */ 2222 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev, 2223 PAGE_SIZE, &spcm->stream[stream].page_table); 2224 if (ret < 0) { 2225 dev_err(sdev->dev, "error: can't alloc page table for %s %d\n", 2226 caps->name, ret); 2227 2228 return ret; 2229 } 2230 2231 /* bind pcm to host comp */ 2232 ret = spcm_bind(sdev, spcm, stream); 2233 if (ret) { 2234 dev_err(sdev->dev, 2235 "error: can't bind pcm to host\n"); 2236 goto free_playback_tables; 2237 } 2238 2239 capture: 2240 stream = SNDRV_PCM_STREAM_CAPTURE; 2241 2242 /* do we need to allocate capture PCM DMA pages */ 2243 if (!spcm->pcm.capture) 2244 return ret; 2245 2246 caps = &spcm->pcm.caps[stream]; 2247 2248 /* allocate capture page table buffer */ 2249 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev, 2250 PAGE_SIZE, &spcm->stream[stream].page_table); 2251 if (ret < 0) { 2252 dev_err(sdev->dev, "error: can't alloc page table for %s %d\n", 2253 caps->name, ret); 2254 goto free_playback_tables; 2255 } 2256 2257 /* bind pcm to host comp */ 2258 ret = spcm_bind(sdev, spcm, stream); 2259 if (ret) { 2260 dev_err(sdev->dev, 2261 "error: can't bind pcm to host\n"); 2262 snd_dma_free_pages(&spcm->stream[stream].page_table); 2263 goto free_playback_tables; 2264 } 2265 2266 return ret; 2267 2268 free_playback_tables: 2269 if (spcm->pcm.playback) 2270 snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_PLAYBACK].page_table); 2271 2272 return ret; 2273 } 2274 2275 static int sof_dai_unload(struct snd_soc_component *scomp, 2276 struct snd_soc_dobj *dobj) 2277 { 2278 struct snd_sof_pcm *spcm = dobj->private; 2279 2280 /* free PCM DMA pages */ 2281 if (spcm->pcm.playback) 2282 snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_PLAYBACK].page_table); 2283 2284 if (spcm->pcm.capture) 2285 snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_CAPTURE].page_table); 2286 2287 /* remove from list and free spcm */ 2288 list_del(&spcm->list); 2289 kfree(spcm); 2290 2291 return 0; 2292 } 2293 2294 static void sof_dai_set_format(struct snd_soc_tplg_hw_config *hw_config, 2295 struct sof_ipc_dai_config *config) 2296 { 2297 /* clock directions wrt codec */ 2298 if (hw_config->bclk_master == SND_SOC_TPLG_BCLK_CM) { 2299 /* codec is bclk master */ 2300 if (hw_config->fsync_master == SND_SOC_TPLG_FSYNC_CM) 2301 config->format |= SOF_DAI_FMT_CBM_CFM; 2302 else 2303 config->format |= SOF_DAI_FMT_CBM_CFS; 2304 } else { 2305 /* codec is bclk slave */ 2306 if (hw_config->fsync_master == SND_SOC_TPLG_FSYNC_CM) 2307 config->format |= SOF_DAI_FMT_CBS_CFM; 2308 else 2309 config->format |= SOF_DAI_FMT_CBS_CFS; 2310 } 2311 2312 /* inverted clocks ? */ 2313 if (hw_config->invert_bclk) { 2314 if (hw_config->invert_fsync) 2315 config->format |= SOF_DAI_FMT_IB_IF; 2316 else 2317 config->format |= SOF_DAI_FMT_IB_NF; 2318 } else { 2319 if (hw_config->invert_fsync) 2320 config->format |= SOF_DAI_FMT_NB_IF; 2321 else 2322 config->format |= SOF_DAI_FMT_NB_NF; 2323 } 2324 } 2325 2326 /* set config for all DAI's with name matching the link name */ 2327 static int sof_set_dai_config(struct snd_sof_dev *sdev, u32 size, 2328 struct snd_soc_dai_link *link, 2329 struct sof_ipc_dai_config *config) 2330 { 2331 struct snd_sof_dai *dai; 2332 int found = 0; 2333 2334 list_for_each_entry(dai, &sdev->dai_list, list) { 2335 if (!dai->name) 2336 continue; 2337 2338 if (strcmp(link->name, dai->name) == 0) { 2339 dai->dai_config = kmemdup(config, size, GFP_KERNEL); 2340 if (!dai->dai_config) 2341 return -ENOMEM; 2342 2343 found = 1; 2344 } 2345 } 2346 2347 /* 2348 * machine driver may define a dai link with playback and capture 2349 * dai enabled, but the dai link in topology would support both, one 2350 * or none of them. Here print a warning message to notify user 2351 */ 2352 if (!found) { 2353 dev_warn(sdev->dev, "warning: failed to find dai for dai link %s", 2354 link->name); 2355 } 2356 2357 return 0; 2358 } 2359 2360 static int sof_link_ssp_load(struct snd_soc_component *scomp, int index, 2361 struct snd_soc_dai_link *link, 2362 struct snd_soc_tplg_link_config *cfg, 2363 struct snd_soc_tplg_hw_config *hw_config, 2364 struct sof_ipc_dai_config *config) 2365 { 2366 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 2367 struct snd_soc_tplg_private *private = &cfg->priv; 2368 struct sof_ipc_reply reply; 2369 u32 size = sizeof(*config); 2370 int ret; 2371 2372 /* handle master/slave and inverted clocks */ 2373 sof_dai_set_format(hw_config, config); 2374 2375 /* init IPC */ 2376 memset(&config->ssp, 0, sizeof(struct sof_ipc_dai_ssp_params)); 2377 config->hdr.size = size; 2378 2379 ret = sof_parse_tokens(scomp, &config->ssp, ssp_tokens, 2380 ARRAY_SIZE(ssp_tokens), private->array, 2381 le32_to_cpu(private->size)); 2382 if (ret != 0) { 2383 dev_err(sdev->dev, "error: parse ssp tokens failed %d\n", 2384 le32_to_cpu(private->size)); 2385 return ret; 2386 } 2387 2388 config->ssp.mclk_rate = le32_to_cpu(hw_config->mclk_rate); 2389 config->ssp.bclk_rate = le32_to_cpu(hw_config->bclk_rate); 2390 config->ssp.fsync_rate = le32_to_cpu(hw_config->fsync_rate); 2391 config->ssp.tdm_slots = le32_to_cpu(hw_config->tdm_slots); 2392 config->ssp.tdm_slot_width = le32_to_cpu(hw_config->tdm_slot_width); 2393 config->ssp.mclk_direction = hw_config->mclk_direction; 2394 config->ssp.rx_slots = le32_to_cpu(hw_config->rx_slots); 2395 config->ssp.tx_slots = le32_to_cpu(hw_config->tx_slots); 2396 2397 dev_dbg(sdev->dev, "tplg: config SSP%d fmt 0x%x mclk %d bclk %d fclk %d width (%d)%d slots %d mclk id %d quirks %d\n", 2398 config->dai_index, config->format, 2399 config->ssp.mclk_rate, config->ssp.bclk_rate, 2400 config->ssp.fsync_rate, config->ssp.sample_valid_bits, 2401 config->ssp.tdm_slot_width, config->ssp.tdm_slots, 2402 config->ssp.mclk_id, config->ssp.quirks); 2403 2404 /* validate SSP fsync rate and channel count */ 2405 if (config->ssp.fsync_rate < 8000 || config->ssp.fsync_rate > 192000) { 2406 dev_err(sdev->dev, "error: invalid fsync rate for SSP%d\n", 2407 config->dai_index); 2408 return -EINVAL; 2409 } 2410 2411 if (config->ssp.tdm_slots < 1 || config->ssp.tdm_slots > 8) { 2412 dev_err(sdev->dev, "error: invalid channel count for SSP%d\n", 2413 config->dai_index); 2414 return -EINVAL; 2415 } 2416 2417 /* send message to DSP */ 2418 ret = sof_ipc_tx_message(sdev->ipc, 2419 config->hdr.cmd, config, size, &reply, 2420 sizeof(reply)); 2421 2422 if (ret < 0) { 2423 dev_err(sdev->dev, "error: failed to set DAI config for SSP%d\n", 2424 config->dai_index); 2425 return ret; 2426 } 2427 2428 /* set config for all DAI's with name matching the link name */ 2429 ret = sof_set_dai_config(sdev, size, link, config); 2430 if (ret < 0) 2431 dev_err(sdev->dev, "error: failed to save DAI config for SSP%d\n", 2432 config->dai_index); 2433 2434 return ret; 2435 } 2436 2437 static int sof_link_dmic_load(struct snd_soc_component *scomp, int index, 2438 struct snd_soc_dai_link *link, 2439 struct snd_soc_tplg_link_config *cfg, 2440 struct snd_soc_tplg_hw_config *hw_config, 2441 struct sof_ipc_dai_config *config) 2442 { 2443 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 2444 struct snd_soc_tplg_private *private = &cfg->priv; 2445 struct sof_ipc_dai_config *ipc_config; 2446 struct sof_ipc_reply reply; 2447 struct sof_ipc_fw_ready *ready = &sdev->fw_ready; 2448 struct sof_ipc_fw_version *v = &ready->version; 2449 u32 size; 2450 int ret, j; 2451 2452 /* 2453 * config is only used for the common params in dmic_params structure 2454 * that does not include the PDM controller config array 2455 * Set the common params to 0. 2456 */ 2457 memset(&config->dmic, 0, sizeof(struct sof_ipc_dai_dmic_params)); 2458 2459 /* get DMIC tokens */ 2460 ret = sof_parse_tokens(scomp, &config->dmic, dmic_tokens, 2461 ARRAY_SIZE(dmic_tokens), private->array, 2462 le32_to_cpu(private->size)); 2463 if (ret != 0) { 2464 dev_err(sdev->dev, "error: parse dmic tokens failed %d\n", 2465 le32_to_cpu(private->size)); 2466 return ret; 2467 } 2468 2469 /* 2470 * allocate memory for dmic dai config accounting for the 2471 * variable number of active pdm controllers 2472 * This will be the ipc payload for setting dai config 2473 */ 2474 size = sizeof(*config) + sizeof(struct sof_ipc_dai_dmic_pdm_ctrl) * 2475 config->dmic.num_pdm_active; 2476 2477 ipc_config = kzalloc(size, GFP_KERNEL); 2478 if (!ipc_config) 2479 return -ENOMEM; 2480 2481 /* copy the common dai config and dmic params */ 2482 memcpy(ipc_config, config, sizeof(*config)); 2483 2484 /* 2485 * alloc memory for private member 2486 * Used to track the pdm config array index currently being parsed 2487 */ 2488 sdev->private = kzalloc(sizeof(u32), GFP_KERNEL); 2489 if (!sdev->private) { 2490 kfree(ipc_config); 2491 return -ENOMEM; 2492 } 2493 2494 /* get DMIC PDM tokens */ 2495 ret = sof_parse_tokens(scomp, &ipc_config->dmic.pdm[0], dmic_pdm_tokens, 2496 ARRAY_SIZE(dmic_pdm_tokens), private->array, 2497 le32_to_cpu(private->size)); 2498 if (ret != 0) { 2499 dev_err(sdev->dev, "error: parse dmic pdm tokens failed %d\n", 2500 le32_to_cpu(private->size)); 2501 goto err; 2502 } 2503 2504 /* set IPC header size */ 2505 ipc_config->hdr.size = size; 2506 2507 /* debug messages */ 2508 dev_dbg(sdev->dev, "tplg: config DMIC%d driver version %d\n", 2509 ipc_config->dai_index, ipc_config->dmic.driver_ipc_version); 2510 dev_dbg(sdev->dev, "pdmclk_min %d pdm_clkmax %d duty_min %hd\n", 2511 ipc_config->dmic.pdmclk_min, ipc_config->dmic.pdmclk_max, 2512 ipc_config->dmic.duty_min); 2513 dev_dbg(sdev->dev, "duty_max %hd fifo_fs %d num_pdms active %d\n", 2514 ipc_config->dmic.duty_max, ipc_config->dmic.fifo_fs, 2515 ipc_config->dmic.num_pdm_active); 2516 dev_dbg(sdev->dev, "fifo word length %hd\n", 2517 ipc_config->dmic.fifo_bits); 2518 2519 for (j = 0; j < ipc_config->dmic.num_pdm_active; j++) { 2520 dev_dbg(sdev->dev, "pdm %hd mic a %hd mic b %hd\n", 2521 ipc_config->dmic.pdm[j].id, 2522 ipc_config->dmic.pdm[j].enable_mic_a, 2523 ipc_config->dmic.pdm[j].enable_mic_b); 2524 dev_dbg(sdev->dev, "pdm %hd polarity a %hd polarity b %hd\n", 2525 ipc_config->dmic.pdm[j].id, 2526 ipc_config->dmic.pdm[j].polarity_mic_a, 2527 ipc_config->dmic.pdm[j].polarity_mic_b); 2528 dev_dbg(sdev->dev, "pdm %hd clk_edge %hd skew %hd\n", 2529 ipc_config->dmic.pdm[j].id, 2530 ipc_config->dmic.pdm[j].clk_edge, 2531 ipc_config->dmic.pdm[j].skew); 2532 } 2533 2534 if (SOF_ABI_VER(v->major, v->minor, v->micro) < SOF_ABI_VER(3, 0, 1)) { 2535 /* this takes care of backwards compatible handling of fifo_bits_b */ 2536 ipc_config->dmic.reserved_2 = ipc_config->dmic.fifo_bits; 2537 } 2538 2539 /* send message to DSP */ 2540 ret = sof_ipc_tx_message(sdev->ipc, 2541 ipc_config->hdr.cmd, ipc_config, size, &reply, 2542 sizeof(reply)); 2543 2544 if (ret < 0) { 2545 dev_err(sdev->dev, 2546 "error: failed to set DAI config for DMIC%d\n", 2547 config->dai_index); 2548 goto err; 2549 } 2550 2551 /* set config for all DAI's with name matching the link name */ 2552 ret = sof_set_dai_config(sdev, size, link, ipc_config); 2553 if (ret < 0) 2554 dev_err(sdev->dev, "error: failed to save DAI config for DMIC%d\n", 2555 config->dai_index); 2556 2557 err: 2558 kfree(sdev->private); 2559 kfree(ipc_config); 2560 2561 return ret; 2562 } 2563 2564 /* 2565 * for hda link, playback and capture are supported by different dai 2566 * in FW. Here get the dai_index, set dma channel of each dai 2567 * and send config to FW. In FW, each dai sets config by dai_index 2568 */ 2569 static int sof_link_hda_process(struct snd_sof_dev *sdev, 2570 struct snd_soc_dai_link *link, 2571 struct sof_ipc_dai_config *config, 2572 int tx_slot, 2573 int rx_slot) 2574 { 2575 struct sof_ipc_reply reply; 2576 u32 size = sizeof(*config); 2577 struct snd_sof_dai *sof_dai; 2578 int found = 0; 2579 int ret; 2580 2581 list_for_each_entry(sof_dai, &sdev->dai_list, list) { 2582 if (!sof_dai->name) 2583 continue; 2584 2585 if (strcmp(link->name, sof_dai->name) == 0) { 2586 if (sof_dai->comp_dai.direction == 2587 SNDRV_PCM_STREAM_PLAYBACK) { 2588 if (!link->dpcm_playback) 2589 return -EINVAL; 2590 2591 config->hda.link_dma_ch = tx_slot; 2592 } else { 2593 if (!link->dpcm_capture) 2594 return -EINVAL; 2595 2596 config->hda.link_dma_ch = rx_slot; 2597 } 2598 2599 config->dai_index = sof_dai->comp_dai.dai_index; 2600 found = 1; 2601 2602 /* save config in dai component */ 2603 sof_dai->dai_config = kmemdup(config, size, GFP_KERNEL); 2604 if (!sof_dai->dai_config) 2605 return -ENOMEM; 2606 2607 /* send message to DSP */ 2608 ret = sof_ipc_tx_message(sdev->ipc, 2609 config->hdr.cmd, config, size, 2610 &reply, sizeof(reply)); 2611 2612 if (ret < 0) { 2613 dev_err(sdev->dev, "error: failed to set DAI config for direction:%d of HDA dai %d\n", 2614 sof_dai->comp_dai.direction, 2615 config->dai_index); 2616 2617 return ret; 2618 } 2619 } 2620 } 2621 2622 /* 2623 * machine driver may define a dai link with playback and capture 2624 * dai enabled, but the dai link in topology would support both, one 2625 * or none of them. Here print a warning message to notify user 2626 */ 2627 if (!found) { 2628 dev_warn(sdev->dev, "warning: failed to find dai for dai link %s", 2629 link->name); 2630 } 2631 2632 return 0; 2633 } 2634 2635 static int sof_link_hda_load(struct snd_soc_component *scomp, int index, 2636 struct snd_soc_dai_link *link, 2637 struct snd_soc_tplg_link_config *cfg, 2638 struct snd_soc_tplg_hw_config *hw_config, 2639 struct sof_ipc_dai_config *config) 2640 { 2641 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 2642 struct snd_soc_dai_link_component dai_component; 2643 struct snd_soc_tplg_private *private = &cfg->priv; 2644 struct snd_soc_dai *dai; 2645 u32 size = sizeof(*config); 2646 u32 tx_num = 0; 2647 u32 tx_slot = 0; 2648 u32 rx_num = 0; 2649 u32 rx_slot = 0; 2650 int ret; 2651 2652 /* init IPC */ 2653 memset(&dai_component, 0, sizeof(dai_component)); 2654 memset(&config->hda, 0, sizeof(struct sof_ipc_dai_hda_params)); 2655 config->hdr.size = size; 2656 2657 /* get any bespoke DAI tokens */ 2658 ret = sof_parse_tokens(scomp, config, hda_tokens, 2659 ARRAY_SIZE(hda_tokens), private->array, 2660 le32_to_cpu(private->size)); 2661 if (ret != 0) { 2662 dev_err(sdev->dev, "error: parse hda tokens failed %d\n", 2663 le32_to_cpu(private->size)); 2664 return ret; 2665 } 2666 2667 dai_component.dai_name = link->cpu_dai_name; 2668 dai = snd_soc_find_dai(&dai_component); 2669 if (!dai) { 2670 dev_err(sdev->dev, "error: failed to find dai %s in %s", 2671 dai_component.dai_name, __func__); 2672 return -EINVAL; 2673 } 2674 2675 if (link->dpcm_playback) 2676 tx_num = 1; 2677 2678 if (link->dpcm_capture) 2679 rx_num = 1; 2680 2681 ret = snd_soc_dai_get_channel_map(dai, &tx_num, &tx_slot, 2682 &rx_num, &rx_slot); 2683 if (ret < 0) { 2684 dev_err(sdev->dev, "error: failed to get dma channel for HDA%d\n", 2685 config->dai_index); 2686 2687 return ret; 2688 } 2689 2690 ret = sof_link_hda_process(sdev, link, config, tx_slot, rx_slot); 2691 if (ret < 0) 2692 dev_err(sdev->dev, "error: failed to process hda dai link %s", 2693 link->name); 2694 2695 return ret; 2696 } 2697 2698 /* DAI link - used for any driver specific init */ 2699 static int sof_link_load(struct snd_soc_component *scomp, int index, 2700 struct snd_soc_dai_link *link, 2701 struct snd_soc_tplg_link_config *cfg) 2702 { 2703 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 2704 struct snd_soc_tplg_private *private = &cfg->priv; 2705 struct sof_ipc_dai_config config; 2706 struct snd_soc_tplg_hw_config *hw_config; 2707 int num_hw_configs; 2708 int ret; 2709 int i = 0; 2710 2711 link->platform_name = dev_name(sdev->dev); 2712 2713 /* 2714 * Set nonatomic property for FE dai links as their trigger action 2715 * involves IPC's. 2716 */ 2717 if (!link->no_pcm) { 2718 link->nonatomic = true; 2719 2720 /* nothing more to do for FE dai links */ 2721 return 0; 2722 } 2723 2724 /* check we have some tokens - we need at least DAI type */ 2725 if (le32_to_cpu(private->size) == 0) { 2726 dev_err(sdev->dev, "error: expected tokens for DAI, none found\n"); 2727 return -EINVAL; 2728 } 2729 2730 /* Send BE DAI link configurations to DSP */ 2731 memset(&config, 0, sizeof(config)); 2732 2733 /* get any common DAI tokens */ 2734 ret = sof_parse_tokens(scomp, &config, dai_link_tokens, 2735 ARRAY_SIZE(dai_link_tokens), private->array, 2736 le32_to_cpu(private->size)); 2737 if (ret != 0) { 2738 dev_err(sdev->dev, "error: parse link tokens failed %d\n", 2739 le32_to_cpu(private->size)); 2740 return ret; 2741 } 2742 2743 /* 2744 * DAI links are expected to have at least 1 hw_config. 2745 * But some older topologies might have no hw_config for HDA dai links. 2746 */ 2747 num_hw_configs = le32_to_cpu(cfg->num_hw_configs); 2748 if (!num_hw_configs) { 2749 if (config.type != SOF_DAI_INTEL_HDA) { 2750 dev_err(sdev->dev, "error: unexpected DAI config count %d!\n", 2751 le32_to_cpu(cfg->num_hw_configs)); 2752 return -EINVAL; 2753 } 2754 } else { 2755 dev_dbg(sdev->dev, "tplg: %d hw_configs found, default id: %d!\n", 2756 cfg->num_hw_configs, le32_to_cpu(cfg->default_hw_config_id)); 2757 2758 for (i = 0; i < num_hw_configs; i++) { 2759 if (cfg->hw_config[i].id == cfg->default_hw_config_id) 2760 break; 2761 } 2762 2763 if (i == num_hw_configs) { 2764 dev_err(sdev->dev, "error: default hw_config id: %d not found!\n", 2765 le32_to_cpu(cfg->default_hw_config_id)); 2766 return -EINVAL; 2767 } 2768 } 2769 2770 /* configure dai IPC message */ 2771 hw_config = &cfg->hw_config[i]; 2772 2773 config.hdr.cmd = SOF_IPC_GLB_DAI_MSG | SOF_IPC_DAI_CONFIG; 2774 config.format = le32_to_cpu(hw_config->fmt); 2775 2776 /* now load DAI specific data and send IPC - type comes from token */ 2777 switch (config.type) { 2778 case SOF_DAI_INTEL_SSP: 2779 ret = sof_link_ssp_load(scomp, index, link, cfg, hw_config, 2780 &config); 2781 break; 2782 case SOF_DAI_INTEL_DMIC: 2783 ret = sof_link_dmic_load(scomp, index, link, cfg, hw_config, 2784 &config); 2785 break; 2786 case SOF_DAI_INTEL_HDA: 2787 ret = sof_link_hda_load(scomp, index, link, cfg, hw_config, 2788 &config); 2789 break; 2790 default: 2791 dev_err(sdev->dev, "error: invalid DAI type %d\n", config.type); 2792 ret = -EINVAL; 2793 break; 2794 } 2795 if (ret < 0) 2796 return ret; 2797 2798 return 0; 2799 } 2800 2801 static int sof_link_hda_unload(struct snd_sof_dev *sdev, 2802 struct snd_soc_dai_link *link) 2803 { 2804 struct snd_soc_dai_link_component dai_component; 2805 struct snd_soc_dai *dai; 2806 int ret = 0; 2807 2808 memset(&dai_component, 0, sizeof(dai_component)); 2809 dai_component.dai_name = link->cpu_dai_name; 2810 dai = snd_soc_find_dai(&dai_component); 2811 if (!dai) { 2812 dev_err(sdev->dev, "error: failed to find dai %s in %s", 2813 dai_component.dai_name, __func__); 2814 return -EINVAL; 2815 } 2816 2817 /* 2818 * FIXME: this call to hw_free is mainly to release the link DMA ID. 2819 * This is abusing the API and handling SOC internals is not 2820 * recommended. This part will be reworked. 2821 */ 2822 if (dai->driver->ops->hw_free) 2823 ret = dai->driver->ops->hw_free(NULL, dai); 2824 if (ret < 0) 2825 dev_err(sdev->dev, "error: failed to free hda resource for %s\n", 2826 link->name); 2827 2828 return ret; 2829 } 2830 2831 static int sof_link_unload(struct snd_soc_component *scomp, 2832 struct snd_soc_dobj *dobj) 2833 { 2834 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 2835 struct snd_soc_dai_link *link = 2836 container_of(dobj, struct snd_soc_dai_link, dobj); 2837 2838 struct snd_sof_dai *sof_dai; 2839 int ret = 0; 2840 2841 /* only BE link is loaded by sof */ 2842 if (!link->no_pcm) 2843 return 0; 2844 2845 list_for_each_entry(sof_dai, &sdev->dai_list, list) { 2846 if (!sof_dai->name) 2847 continue; 2848 2849 if (strcmp(link->name, sof_dai->name) == 0) 2850 goto found; 2851 } 2852 2853 dev_err(sdev->dev, "error: failed to find dai %s in %s", 2854 link->name, __func__); 2855 return -EINVAL; 2856 found: 2857 2858 switch (sof_dai->dai_config->type) { 2859 case SOF_DAI_INTEL_SSP: 2860 case SOF_DAI_INTEL_DMIC: 2861 /* no resource needs to be released for SSP and DMIC */ 2862 break; 2863 case SOF_DAI_INTEL_HDA: 2864 ret = sof_link_hda_unload(sdev, link); 2865 break; 2866 default: 2867 dev_err(sdev->dev, "error: invalid DAI type %d\n", 2868 sof_dai->dai_config->type); 2869 ret = -EINVAL; 2870 break; 2871 } 2872 2873 return ret; 2874 } 2875 2876 /* DAI link - used for any driver specific init */ 2877 static int sof_route_load(struct snd_soc_component *scomp, int index, 2878 struct snd_soc_dapm_route *route) 2879 { 2880 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 2881 struct sof_ipc_pipe_comp_connect *connect; 2882 struct snd_sof_widget *source_swidget, *sink_swidget; 2883 struct snd_soc_dobj *dobj = &route->dobj; 2884 struct snd_sof_route *sroute; 2885 struct sof_ipc_reply reply; 2886 int ret = 0; 2887 2888 /* allocate memory for sroute and connect */ 2889 sroute = kzalloc(sizeof(*sroute), GFP_KERNEL); 2890 if (!sroute) 2891 return -ENOMEM; 2892 2893 sroute->sdev = sdev; 2894 2895 connect = kzalloc(sizeof(*connect), GFP_KERNEL); 2896 if (!connect) { 2897 kfree(sroute); 2898 return -ENOMEM; 2899 } 2900 2901 connect->hdr.size = sizeof(*connect); 2902 connect->hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_CONNECT; 2903 2904 dev_dbg(sdev->dev, "sink %s control %s source %s\n", 2905 route->sink, route->control ? route->control : "none", 2906 route->source); 2907 2908 /* source component */ 2909 source_swidget = snd_sof_find_swidget(sdev, (char *)route->source); 2910 if (!source_swidget) { 2911 dev_err(sdev->dev, "error: source %s not found\n", 2912 route->source); 2913 ret = -EINVAL; 2914 goto err; 2915 } 2916 2917 /* 2918 * Virtual widgets of type output/out_drv may be added in topology 2919 * for compatibility. These are not handled by the FW. 2920 * So, don't send routes whose source/sink widget is of such types 2921 * to the DSP. 2922 */ 2923 if (source_swidget->id == snd_soc_dapm_out_drv || 2924 source_swidget->id == snd_soc_dapm_output) 2925 goto err; 2926 2927 connect->source_id = source_swidget->comp_id; 2928 2929 /* sink component */ 2930 sink_swidget = snd_sof_find_swidget(sdev, (char *)route->sink); 2931 if (!sink_swidget) { 2932 dev_err(sdev->dev, "error: sink %s not found\n", 2933 route->sink); 2934 ret = -EINVAL; 2935 goto err; 2936 } 2937 2938 /* 2939 * Don't send routes whose sink widget is of type 2940 * output or out_drv to the DSP 2941 */ 2942 if (sink_swidget->id == snd_soc_dapm_out_drv || 2943 sink_swidget->id == snd_soc_dapm_output) 2944 goto err; 2945 2946 connect->sink_id = sink_swidget->comp_id; 2947 2948 /* 2949 * For virtual routes, both sink and source are not 2950 * buffer. Since only buffer linked to component is supported by 2951 * FW, others are reported as error, add check in route function, 2952 * do not send it to FW when both source and sink are not buffer 2953 */ 2954 if (source_swidget->id != snd_soc_dapm_buffer && 2955 sink_swidget->id != snd_soc_dapm_buffer) { 2956 dev_dbg(sdev->dev, "warning: neither Linked source component %s nor sink component %s is of buffer type, ignoring link\n", 2957 route->source, route->sink); 2958 ret = 0; 2959 goto err; 2960 } else { 2961 ret = sof_ipc_tx_message(sdev->ipc, 2962 connect->hdr.cmd, 2963 connect, sizeof(*connect), 2964 &reply, sizeof(reply)); 2965 2966 /* check IPC return value */ 2967 if (ret < 0) { 2968 dev_err(sdev->dev, "error: failed to add route sink %s control %s source %s\n", 2969 route->sink, 2970 route->control ? route->control : "none", 2971 route->source); 2972 goto err; 2973 } 2974 2975 /* check IPC reply */ 2976 if (reply.error < 0) { 2977 dev_err(sdev->dev, "error: DSP failed to add route sink %s control %s source %s result %d\n", 2978 route->sink, 2979 route->control ? route->control : "none", 2980 route->source, reply.error); 2981 ret = reply.error; 2982 goto err; 2983 } 2984 2985 sroute->route = route; 2986 dobj->private = sroute; 2987 sroute->private = connect; 2988 2989 /* add route to route list */ 2990 list_add(&sroute->list, &sdev->route_list); 2991 2992 return ret; 2993 } 2994 2995 err: 2996 kfree(connect); 2997 kfree(sroute); 2998 return ret; 2999 } 3000 3001 int snd_sof_complete_pipeline(struct snd_sof_dev *sdev, 3002 struct snd_sof_widget *swidget) 3003 { 3004 struct sof_ipc_pipe_ready ready; 3005 struct sof_ipc_reply reply; 3006 int ret; 3007 3008 dev_dbg(sdev->dev, "tplg: complete pipeline %s id %d\n", 3009 swidget->widget->name, swidget->comp_id); 3010 3011 memset(&ready, 0, sizeof(ready)); 3012 ready.hdr.size = sizeof(ready); 3013 ready.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_PIPE_COMPLETE; 3014 ready.comp_id = swidget->comp_id; 3015 3016 ret = sof_ipc_tx_message(sdev->ipc, 3017 ready.hdr.cmd, &ready, sizeof(ready), &reply, 3018 sizeof(reply)); 3019 if (ret < 0) 3020 return ret; 3021 return 1; 3022 } 3023 3024 /* completion - called at completion of firmware loading */ 3025 static void sof_complete(struct snd_soc_component *scomp) 3026 { 3027 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 3028 struct snd_sof_widget *swidget; 3029 3030 /* some widget types require completion notificattion */ 3031 list_for_each_entry(swidget, &sdev->widget_list, list) { 3032 if (swidget->complete) 3033 continue; 3034 3035 switch (swidget->id) { 3036 case snd_soc_dapm_scheduler: 3037 swidget->complete = 3038 snd_sof_complete_pipeline(sdev, swidget); 3039 break; 3040 default: 3041 break; 3042 } 3043 } 3044 } 3045 3046 /* manifest - optional to inform component of manifest */ 3047 static int sof_manifest(struct snd_soc_component *scomp, int index, 3048 struct snd_soc_tplg_manifest *man) 3049 { 3050 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 3051 u32 size; 3052 u32 abi_version; 3053 3054 size = le32_to_cpu(man->priv.size); 3055 3056 /* backward compatible with tplg without ABI info */ 3057 if (!size) { 3058 dev_dbg(sdev->dev, "No topology ABI info\n"); 3059 return 0; 3060 } 3061 3062 if (size != SOF_TPLG_ABI_SIZE) { 3063 dev_err(sdev->dev, "error: invalid topology ABI size\n"); 3064 return -EINVAL; 3065 } 3066 3067 dev_info(sdev->dev, 3068 "Topology: ABI %d:%d:%d Kernel ABI %d:%d:%d\n", 3069 man->priv.data[0], man->priv.data[1], 3070 man->priv.data[2], SOF_ABI_MAJOR, SOF_ABI_MINOR, 3071 SOF_ABI_PATCH); 3072 3073 abi_version = SOF_ABI_VER(man->priv.data[0], 3074 man->priv.data[1], 3075 man->priv.data[2]); 3076 3077 if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, abi_version)) { 3078 dev_err(sdev->dev, "error: incompatible topology ABI version\n"); 3079 return -EINVAL; 3080 } 3081 3082 if (abi_version > SOF_ABI_VERSION) { 3083 if (!IS_ENABLED(CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS)) { 3084 dev_warn(sdev->dev, "warn: topology ABI is more recent than kernel\n"); 3085 } else { 3086 dev_err(sdev->dev, "error: topology ABI is more recent than kernel\n"); 3087 return -EINVAL; 3088 } 3089 } 3090 3091 return 0; 3092 } 3093 3094 /* vendor specific kcontrol handlers available for binding */ 3095 static const struct snd_soc_tplg_kcontrol_ops sof_io_ops[] = { 3096 {SOF_TPLG_KCTL_VOL_ID, snd_sof_volume_get, snd_sof_volume_put}, 3097 {SOF_TPLG_KCTL_BYTES_ID, snd_sof_bytes_get, snd_sof_bytes_put}, 3098 {SOF_TPLG_KCTL_ENUM_ID, snd_sof_enum_get, snd_sof_enum_put}, 3099 {SOF_TPLG_KCTL_SWITCH_ID, snd_sof_switch_get, snd_sof_switch_put}, 3100 }; 3101 3102 /* vendor specific bytes ext handlers available for binding */ 3103 static const struct snd_soc_tplg_bytes_ext_ops sof_bytes_ext_ops[] = { 3104 {SOF_TPLG_KCTL_BYTES_ID, snd_sof_bytes_ext_get, snd_sof_bytes_ext_put}, 3105 }; 3106 3107 static struct snd_soc_tplg_ops sof_tplg_ops = { 3108 /* external kcontrol init - used for any driver specific init */ 3109 .control_load = sof_control_load, 3110 .control_unload = sof_control_unload, 3111 3112 /* external kcontrol init - used for any driver specific init */ 3113 .dapm_route_load = sof_route_load, 3114 .dapm_route_unload = sof_route_unload, 3115 3116 /* external widget init - used for any driver specific init */ 3117 /* .widget_load is not currently used */ 3118 .widget_ready = sof_widget_ready, 3119 .widget_unload = sof_widget_unload, 3120 3121 /* FE DAI - used for any driver specific init */ 3122 .dai_load = sof_dai_load, 3123 .dai_unload = sof_dai_unload, 3124 3125 /* DAI link - used for any driver specific init */ 3126 .link_load = sof_link_load, 3127 .link_unload = sof_link_unload, 3128 3129 /* completion - called at completion of firmware loading */ 3130 .complete = sof_complete, 3131 3132 /* manifest - optional to inform component of manifest */ 3133 .manifest = sof_manifest, 3134 3135 /* vendor specific kcontrol handlers available for binding */ 3136 .io_ops = sof_io_ops, 3137 .io_ops_count = ARRAY_SIZE(sof_io_ops), 3138 3139 /* vendor specific bytes ext handlers available for binding */ 3140 .bytes_ext_ops = sof_bytes_ext_ops, 3141 .bytes_ext_ops_count = ARRAY_SIZE(sof_bytes_ext_ops), 3142 }; 3143 3144 int snd_sof_init_topology(struct snd_sof_dev *sdev, 3145 struct snd_soc_tplg_ops *ops) 3146 { 3147 /* TODO: support linked list of topologies */ 3148 sdev->tplg_ops = ops; 3149 return 0; 3150 } 3151 EXPORT_SYMBOL(snd_sof_init_topology); 3152 3153 int snd_sof_load_topology(struct snd_sof_dev *sdev, const char *file) 3154 { 3155 const struct firmware *fw; 3156 int ret; 3157 3158 dev_dbg(sdev->dev, "loading topology:%s\n", file); 3159 3160 ret = request_firmware(&fw, file, sdev->dev); 3161 if (ret < 0) { 3162 dev_err(sdev->dev, "error: tplg request firmware %s failed err: %d\n", 3163 file, ret); 3164 return ret; 3165 } 3166 3167 ret = snd_soc_tplg_component_load(sdev->component, 3168 &sof_tplg_ops, fw, 3169 SND_SOC_TPLG_INDEX_ALL); 3170 if (ret < 0) { 3171 dev_err(sdev->dev, "error: tplg component load failed %d\n", 3172 ret); 3173 ret = -EINVAL; 3174 } 3175 3176 release_firmware(fw); 3177 return ret; 3178 } 3179 EXPORT_SYMBOL(snd_sof_load_topology); 3180