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