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