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