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