1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2 //
3 // This file is provided under a dual BSD/GPLv2 license. When using or
4 // redistributing this file, you may do so under either license.
5 //
6 // Copyright(c) 2018 Intel Corporation
7 //
8 // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
9 //
10
11 #include <linux/bits.h>
12 #include <linux/device.h>
13 #include <linux/errno.h>
14 #include <linux/firmware.h>
15 #include <linux/workqueue.h>
16 #include <sound/tlv.h>
17 #include <uapi/sound/sof/tokens.h>
18 #include "sof-priv.h"
19 #include "sof-audio.h"
20 #include "ops.h"
21
22 static bool disable_function_topology;
23 module_param(disable_function_topology, bool, 0444);
24 MODULE_PARM_DESC(disable_function_topology, "Disable function topology loading");
25
26 #define COMP_ID_UNASSIGNED 0xffffffff
27 /*
28 * Constants used in the computation of linear volume gain
29 * from dB gain 20th root of 10 in Q1.16 fixed-point notation
30 */
31 #define VOL_TWENTIETH_ROOT_OF_TEN 73533
32 /* 40th root of 10 in Q1.16 fixed-point notation*/
33 #define VOL_FORTIETH_ROOT_OF_TEN 69419
34
35 /* 0.5 dB step value in topology TLV */
36 #define VOL_HALF_DB_STEP 50
37
38 /* TLV data items */
39 #define TLV_MIN 0
40 #define TLV_STEP 1
41 #define TLV_MUTE 2
42
43 /**
44 * sof_update_ipc_object - Parse multiple sets of tokens within the token array associated with the
45 * token ID.
46 * @scomp: pointer to SOC component
47 * @object: target IPC struct to save the parsed values
48 * @token_id: token ID for the token array to be searched
49 * @tuples: pointer to the tuples array
50 * @num_tuples: number of tuples in the tuples array
51 * @object_size: size of the object
52 * @token_instance_num: number of times the same @token_id needs to be parsed i.e. the function
53 * looks for @token_instance_num of each token in the token array associated
54 * with the @token_id
55 */
sof_update_ipc_object(struct snd_soc_component * scomp,void * object,enum sof_tokens token_id,struct snd_sof_tuple * tuples,int num_tuples,size_t object_size,int token_instance_num)56 int sof_update_ipc_object(struct snd_soc_component *scomp, void *object, enum sof_tokens token_id,
57 struct snd_sof_tuple *tuples, int num_tuples,
58 size_t object_size, int token_instance_num)
59 {
60 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
61 const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
62 const struct sof_token_info *token_list;
63 const struct sof_topology_token *tokens;
64 int i, j;
65
66 token_list = tplg_ops ? tplg_ops->token_list : NULL;
67 /* nothing to do if token_list is NULL */
68 if (!token_list)
69 return 0;
70
71 if (token_list[token_id].count < 0) {
72 dev_err(scomp->dev, "Invalid token count for token ID: %d\n", token_id);
73 return -EINVAL;
74 }
75
76 /* No tokens to match */
77 if (!token_list[token_id].count)
78 return 0;
79
80 tokens = token_list[token_id].tokens;
81 if (!tokens) {
82 dev_err(scomp->dev, "Invalid tokens for token id: %d\n", token_id);
83 return -EINVAL;
84 }
85
86 for (i = 0; i < token_list[token_id].count; i++) {
87 int offset = 0;
88 int num_tokens_matched = 0;
89
90 for (j = 0; j < num_tuples; j++) {
91 if (tokens[i].token == tuples[j].token) {
92 switch (tokens[i].type) {
93 case SND_SOC_TPLG_TUPLE_TYPE_WORD:
94 {
95 u32 *val = (u32 *)((u8 *)object + tokens[i].offset +
96 offset);
97
98 *val = tuples[j].value.v;
99 break;
100 }
101 case SND_SOC_TPLG_TUPLE_TYPE_SHORT:
102 case SND_SOC_TPLG_TUPLE_TYPE_BOOL:
103 {
104 u16 *val = (u16 *)((u8 *)object + tokens[i].offset +
105 offset);
106
107 *val = (u16)tuples[j].value.v;
108 break;
109 }
110 case SND_SOC_TPLG_TUPLE_TYPE_STRING:
111 {
112 if (!tokens[i].get_token) {
113 dev_err(scomp->dev,
114 "get_token not defined for token %d in %s\n",
115 tokens[i].token, token_list[token_id].name);
116 return -EINVAL;
117 }
118
119 tokens[i].get_token((void *)tuples[j].value.s, object,
120 tokens[i].offset + offset);
121 break;
122 }
123 default:
124 break;
125 }
126
127 num_tokens_matched++;
128
129 /* found all required sets of current token. Move to the next one */
130 if (!(num_tokens_matched % token_instance_num))
131 break;
132
133 /* move to the next object */
134 offset += object_size;
135 }
136 }
137 }
138
139 return 0;
140 }
141
get_tlv_data(const int * p,int tlv[SOF_TLV_ITEMS])142 static inline int get_tlv_data(const int *p, int tlv[SOF_TLV_ITEMS])
143 {
144 /* we only support dB scale TLV type at the moment */
145 if ((int)p[SNDRV_CTL_TLVO_TYPE] != SNDRV_CTL_TLVT_DB_SCALE)
146 return -EINVAL;
147
148 /* min value in topology tlv data is multiplied by 100 */
149 tlv[TLV_MIN] = (int)p[SNDRV_CTL_TLVO_DB_SCALE_MIN] / 100;
150
151 /* volume steps */
152 tlv[TLV_STEP] = (int)(p[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] &
153 TLV_DB_SCALE_MASK);
154
155 /* mute ON/OFF */
156 if ((p[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] &
157 TLV_DB_SCALE_MUTE) == 0)
158 tlv[TLV_MUTE] = 0;
159 else
160 tlv[TLV_MUTE] = 1;
161
162 return 0;
163 }
164
165 /*
166 * Function to truncate an unsigned 64-bit number
167 * by x bits and return 32-bit unsigned number. This
168 * function also takes care of rounding while truncating
169 */
vol_shift_64(u64 i,u32 x)170 static inline u32 vol_shift_64(u64 i, u32 x)
171 {
172 /* do not truncate more than 32 bits */
173 if (x > 32)
174 x = 32;
175
176 if (x == 0)
177 return (u32)i;
178
179 return (u32)(((i >> (x - 1)) + 1) >> 1);
180 }
181
182 /*
183 * Function to compute a ^ exp where,
184 * a is a fractional number represented by a fixed-point
185 * integer with a fractional world length of "fwl"
186 * exp is an integer
187 * fwl is the fractional word length
188 * Return value is a fractional number represented by a
189 * fixed-point integer with a fractional word length of "fwl"
190 */
vol_pow32(u32 a,int exp,u32 fwl)191 static u32 vol_pow32(u32 a, int exp, u32 fwl)
192 {
193 int i, iter;
194 u32 power = 1 << fwl;
195 u64 numerator;
196
197 /* if exponent is 0, return 1 */
198 if (exp == 0)
199 return power;
200
201 /* determine the number of iterations based on the exponent */
202 if (exp < 0)
203 iter = exp * -1;
204 else
205 iter = exp;
206
207 /* mutiply a "iter" times to compute power */
208 for (i = 0; i < iter; i++) {
209 /*
210 * Product of 2 Qx.fwl fixed-point numbers yields a Q2*x.2*fwl
211 * Truncate product back to fwl fractional bits with rounding
212 */
213 power = vol_shift_64((u64)power * a, fwl);
214 }
215
216 if (exp > 0) {
217 /* if exp is positive, return the result */
218 return power;
219 }
220
221 /* if exp is negative, return the multiplicative inverse */
222 numerator = (u64)1 << (fwl << 1);
223 do_div(numerator, power);
224
225 return (u32)numerator;
226 }
227
228 /*
229 * Function to calculate volume gain from TLV data.
230 * This function can only handle gain steps that are multiples of 0.5 dB
231 */
vol_compute_gain(u32 value,int * tlv)232 u32 vol_compute_gain(u32 value, int *tlv)
233 {
234 int dB_gain;
235 u32 linear_gain;
236 int f_step;
237
238 /* mute volume */
239 if (value == 0 && tlv[TLV_MUTE])
240 return 0;
241
242 /*
243 * compute dB gain from tlv. tlv_step
244 * in topology is multiplied by 100
245 */
246 dB_gain = tlv[TLV_MIN] + (value * tlv[TLV_STEP]) / 100;
247
248 /*
249 * compute linear gain represented by fixed-point
250 * int with VOLUME_FWL fractional bits
251 */
252 linear_gain = vol_pow32(VOL_TWENTIETH_ROOT_OF_TEN, dB_gain, VOLUME_FWL);
253
254 /* extract the fractional part of volume step */
255 f_step = tlv[TLV_STEP] - (tlv[TLV_STEP] / 100);
256
257 /* if volume step is an odd multiple of 0.5 dB */
258 if (f_step == VOL_HALF_DB_STEP && (value & 1))
259 linear_gain = vol_shift_64((u64)linear_gain *
260 VOL_FORTIETH_ROOT_OF_TEN,
261 VOLUME_FWL);
262
263 return linear_gain;
264 }
265
266 /*
267 * Set up volume table for kcontrols from tlv data
268 * "size" specifies the number of entries in the table
269 */
set_up_volume_table(struct snd_sof_control * scontrol,int tlv[SOF_TLV_ITEMS],int size)270 static int set_up_volume_table(struct snd_sof_control *scontrol,
271 int tlv[SOF_TLV_ITEMS], int size)
272 {
273 struct snd_soc_component *scomp = scontrol->scomp;
274 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
275 const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
276
277 if (tplg_ops && tplg_ops->control && tplg_ops->control->set_up_volume_table)
278 return tplg_ops->control->set_up_volume_table(scontrol, tlv, size);
279
280 dev_err(scomp->dev, "Mandatory op %s not set\n", __func__);
281 return -EINVAL;
282 }
283
284 struct sof_dai_types {
285 const char *name;
286 enum sof_ipc_dai_type type;
287 };
288
289 static const struct sof_dai_types sof_dais[] = {
290 {"SSP", SOF_DAI_INTEL_SSP},
291 {"HDA", SOF_DAI_INTEL_HDA},
292 {"DMIC", SOF_DAI_INTEL_DMIC},
293 {"ALH", SOF_DAI_INTEL_ALH},
294 {"SAI", SOF_DAI_IMX_SAI},
295 {"ESAI", SOF_DAI_IMX_ESAI},
296 {"ACPBT", SOF_DAI_AMD_BT},
297 {"ACPSP", SOF_DAI_AMD_SP},
298 {"ACPDMIC", SOF_DAI_AMD_DMIC},
299 {"ACPHS", SOF_DAI_AMD_HS},
300 {"AFE", SOF_DAI_MEDIATEK_AFE},
301 {"ACPSP_VIRTUAL", SOF_DAI_AMD_SP_VIRTUAL},
302 {"ACPHS_VIRTUAL", SOF_DAI_AMD_HS_VIRTUAL},
303 {"MICFIL", SOF_DAI_IMX_MICFIL},
304 {"ACP_SDW", SOF_DAI_AMD_SDW},
305
306 };
307
find_dai(const char * name)308 static enum sof_ipc_dai_type find_dai(const char *name)
309 {
310 int i;
311
312 for (i = 0; i < ARRAY_SIZE(sof_dais); i++) {
313 if (strcmp(name, sof_dais[i].name) == 0)
314 return sof_dais[i].type;
315 }
316
317 return SOF_DAI_INTEL_NONE;
318 }
319
320 /*
321 * Supported Frame format types and lookup, add new ones to end of list.
322 */
323
324 struct sof_frame_types {
325 const char *name;
326 enum sof_ipc_frame frame;
327 };
328
329 static const struct sof_frame_types sof_frames[] = {
330 {"s16le", SOF_IPC_FRAME_S16_LE},
331 {"s24le", SOF_IPC_FRAME_S24_4LE},
332 {"s32le", SOF_IPC_FRAME_S32_LE},
333 {"float", SOF_IPC_FRAME_FLOAT},
334 };
335
find_format(const char * name)336 static enum sof_ipc_frame find_format(const char *name)
337 {
338 int i;
339
340 for (i = 0; i < ARRAY_SIZE(sof_frames); i++) {
341 if (strcmp(name, sof_frames[i].name) == 0)
342 return sof_frames[i].frame;
343 }
344
345 /* use s32le if nothing is specified */
346 return SOF_IPC_FRAME_S32_LE;
347 }
348
get_token_u32(void * elem,void * object,u32 offset)349 int get_token_u32(void *elem, void *object, u32 offset)
350 {
351 struct snd_soc_tplg_vendor_value_elem *velem = elem;
352 u32 *val = (u32 *)((u8 *)object + offset);
353
354 *val = le32_to_cpu(velem->value);
355 return 0;
356 }
357
get_token_u16(void * elem,void * object,u32 offset)358 int get_token_u16(void *elem, void *object, u32 offset)
359 {
360 struct snd_soc_tplg_vendor_value_elem *velem = elem;
361 u16 *val = (u16 *)((u8 *)object + offset);
362
363 *val = (u16)le32_to_cpu(velem->value);
364 return 0;
365 }
366
get_token_uuid(void * elem,void * object,u32 offset)367 int get_token_uuid(void *elem, void *object, u32 offset)
368 {
369 struct snd_soc_tplg_vendor_uuid_elem *velem = elem;
370 u8 *dst = (u8 *)object + offset;
371
372 memcpy(dst, velem->uuid, UUID_SIZE);
373
374 return 0;
375 }
376
377 /*
378 * The string gets from topology will be stored in heap, the owner only
379 * holds a char* member point to the heap.
380 */
get_token_string(void * elem,void * object,u32 offset)381 int get_token_string(void *elem, void *object, u32 offset)
382 {
383 /* "dst" here points to the char* member of the owner */
384 char **dst = (char **)((u8 *)object + offset);
385
386 *dst = kstrdup(elem, GFP_KERNEL);
387 if (!*dst)
388 return -ENOMEM;
389 return 0;
390 };
391
get_token_comp_format(void * elem,void * object,u32 offset)392 int get_token_comp_format(void *elem, void *object, u32 offset)
393 {
394 u32 *val = (u32 *)((u8 *)object + offset);
395
396 *val = find_format((const char *)elem);
397 return 0;
398 }
399
get_token_dai_type(void * elem,void * object,u32 offset)400 int get_token_dai_type(void *elem, void *object, u32 offset)
401 {
402 u32 *val = (u32 *)((u8 *)object + offset);
403
404 *val = find_dai((const char *)elem);
405 return 0;
406 }
407
408 /* PCM */
409 static const struct sof_topology_token stream_tokens[] = {
410 {SOF_TKN_STREAM_PLAYBACK_COMPATIBLE_D0I3, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16,
411 offsetof(struct snd_sof_pcm, stream[0].d0i3_compatible)},
412 {SOF_TKN_STREAM_CAPTURE_COMPATIBLE_D0I3, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16,
413 offsetof(struct snd_sof_pcm, stream[1].d0i3_compatible)},
414 {SOF_TKN_STREAM_PLAYBACK_PAUSE_SUPPORTED, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16,
415 offsetof(struct snd_sof_pcm, stream[0].pause_supported)},
416 {SOF_TKN_STREAM_CAPTURE_PAUSE_SUPPORTED, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16,
417 offsetof(struct snd_sof_pcm, stream[1].pause_supported)},
418 };
419
420 /* Leds */
421 static const struct sof_topology_token led_tokens[] = {
422 {SOF_TKN_MUTE_LED_USE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
423 offsetof(struct snd_sof_led_control, use_led)},
424 {SOF_TKN_MUTE_LED_DIRECTION, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
425 offsetof(struct snd_sof_led_control, direction)},
426 };
427
428 static const struct sof_topology_token comp_pin_tokens[] = {
429 {SOF_TKN_COMP_NUM_INPUT_PINS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
430 offsetof(struct snd_sof_widget, num_input_pins)},
431 {SOF_TKN_COMP_NUM_OUTPUT_PINS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
432 offsetof(struct snd_sof_widget, num_output_pins)},
433 };
434
435 static const struct sof_topology_token comp_input_pin_binding_tokens[] = {
436 {SOF_TKN_COMP_INPUT_PIN_BINDING_WNAME, SND_SOC_TPLG_TUPLE_TYPE_STRING,
437 get_token_string, 0},
438 };
439
440 static const struct sof_topology_token comp_output_pin_binding_tokens[] = {
441 {SOF_TKN_COMP_OUTPUT_PIN_BINDING_WNAME, SND_SOC_TPLG_TUPLE_TYPE_STRING,
442 get_token_string, 0},
443 };
444
445 /**
446 * sof_parse_uuid_tokens - Parse multiple sets of UUID tokens
447 * @scomp: pointer to soc component
448 * @object: target ipc struct for parsed values
449 * @offset: offset within the object pointer
450 * @tokens: array of struct sof_topology_token containing the tokens to be matched
451 * @num_tokens: number of tokens in tokens array
452 * @array: source pointer to consecutive vendor arrays in topology
453 *
454 * This function parses multiple sets of string type tokens in vendor arrays
455 */
sof_parse_uuid_tokens(struct snd_soc_component * scomp,void * object,size_t offset,const struct sof_topology_token * tokens,int num_tokens,struct snd_soc_tplg_vendor_array * array)456 static int sof_parse_uuid_tokens(struct snd_soc_component *scomp,
457 void *object, size_t offset,
458 const struct sof_topology_token *tokens, int num_tokens,
459 struct snd_soc_tplg_vendor_array *array)
460 {
461 struct snd_soc_tplg_vendor_uuid_elem *elem;
462 int found = 0;
463 int i, j;
464
465 /* parse element by element */
466 for (i = 0; i < le32_to_cpu(array->num_elems); i++) {
467 elem = &array->uuid[i];
468
469 /* search for token */
470 for (j = 0; j < num_tokens; j++) {
471 /* match token type */
472 if (tokens[j].type != SND_SOC_TPLG_TUPLE_TYPE_UUID)
473 continue;
474
475 /* match token id */
476 if (tokens[j].token != le32_to_cpu(elem->token))
477 continue;
478
479 /* matched - now load token */
480 tokens[j].get_token(elem, object,
481 offset + tokens[j].offset);
482
483 found++;
484 }
485 }
486
487 return found;
488 }
489
490 /**
491 * sof_copy_tuples - Parse tokens and copy them to the @tuples array
492 * @sdev: pointer to struct snd_sof_dev
493 * @array: source pointer to consecutive vendor arrays in topology
494 * @array_size: size of @array
495 * @token_id: Token ID associated with a token array
496 * @token_instance_num: number of times the same @token_id needs to be parsed i.e. the function
497 * looks for @token_instance_num of each token in the token array associated
498 * with the @token_id
499 * @tuples: tuples array to copy the matched tuples to
500 * @tuples_size: size of @tuples
501 * @num_copied_tuples: pointer to the number of copied tuples in the tuples array
502 *
503 */
sof_copy_tuples(struct snd_sof_dev * sdev,struct snd_soc_tplg_vendor_array * array,int array_size,u32 token_id,int token_instance_num,struct snd_sof_tuple * tuples,int tuples_size,int * num_copied_tuples)504 static int sof_copy_tuples(struct snd_sof_dev *sdev, struct snd_soc_tplg_vendor_array *array,
505 int array_size, u32 token_id, int token_instance_num,
506 struct snd_sof_tuple *tuples, int tuples_size, int *num_copied_tuples)
507 {
508 const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
509 const struct sof_token_info *token_list;
510 const struct sof_topology_token *tokens;
511 int found = 0;
512 int num_tokens, asize;
513 int i, j;
514
515 token_list = tplg_ops ? tplg_ops->token_list : NULL;
516 /* nothing to do if token_list is NULL */
517 if (!token_list)
518 return 0;
519
520 if (!tuples || !num_copied_tuples) {
521 dev_err(sdev->dev, "Invalid tuples array\n");
522 return -EINVAL;
523 }
524
525 tokens = token_list[token_id].tokens;
526 num_tokens = token_list[token_id].count;
527
528 if (!tokens) {
529 dev_err(sdev->dev, "No token array defined for token ID: %d\n", token_id);
530 return -EINVAL;
531 }
532
533 /* check if there's space in the tuples array for new tokens */
534 if (*num_copied_tuples >= tuples_size) {
535 dev_err(sdev->dev, "No space in tuples array for new tokens from %s",
536 token_list[token_id].name);
537 return -EINVAL;
538 }
539
540 while (array_size > 0 && found < num_tokens * token_instance_num) {
541 asize = le32_to_cpu(array->size);
542
543 /* validate asize */
544 if (asize < 0) {
545 dev_err(sdev->dev, "Invalid array size 0x%x\n", asize);
546 return -EINVAL;
547 }
548
549 /* make sure there is enough data before parsing */
550 array_size -= asize;
551 if (array_size < 0) {
552 dev_err(sdev->dev, "Invalid array size 0x%x\n", asize);
553 return -EINVAL;
554 }
555
556 /* parse element by element */
557 for (i = 0; i < le32_to_cpu(array->num_elems); i++) {
558 /* search for token */
559 for (j = 0; j < num_tokens; j++) {
560 /* match token type */
561 if (!(tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_WORD ||
562 tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_SHORT ||
563 tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_BYTE ||
564 tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_BOOL ||
565 tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_STRING))
566 continue;
567
568 if (tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_STRING) {
569 struct snd_soc_tplg_vendor_string_elem *elem;
570
571 elem = &array->string[i];
572
573 /* match token id */
574 if (tokens[j].token != le32_to_cpu(elem->token))
575 continue;
576
577 tuples[*num_copied_tuples].token = tokens[j].token;
578 tuples[*num_copied_tuples].value.s =
579 devm_kasprintf(sdev->dev, GFP_KERNEL,
580 "%s", elem->string);
581 if (!tuples[*num_copied_tuples].value.s)
582 return -ENOMEM;
583 } else {
584 struct snd_soc_tplg_vendor_value_elem *elem;
585
586 elem = &array->value[i];
587
588 /* match token id */
589 if (tokens[j].token != le32_to_cpu(elem->token))
590 continue;
591
592 tuples[*num_copied_tuples].token = tokens[j].token;
593 tuples[*num_copied_tuples].value.v =
594 le32_to_cpu(elem->value);
595 }
596 found++;
597 (*num_copied_tuples)++;
598
599 /* stop if there's no space for any more new tuples */
600 if (*num_copied_tuples == tuples_size)
601 return 0;
602 }
603
604 /* stop when we've found the required token instances */
605 if (found == num_tokens * token_instance_num)
606 return 0;
607 }
608
609 /* next array */
610 array = (struct snd_soc_tplg_vendor_array *)((u8 *)array + asize);
611 }
612
613 return 0;
614 }
615
616 /**
617 * sof_parse_string_tokens - Parse multiple sets of tokens
618 * @scomp: pointer to soc component
619 * @object: target ipc struct for parsed values
620 * @offset: offset within the object pointer
621 * @tokens: array of struct sof_topology_token containing the tokens to be matched
622 * @num_tokens: number of tokens in tokens array
623 * @array: source pointer to consecutive vendor arrays in topology
624 *
625 * This function parses multiple sets of string type tokens in vendor arrays
626 */
sof_parse_string_tokens(struct snd_soc_component * scomp,void * object,int offset,const struct sof_topology_token * tokens,int num_tokens,struct snd_soc_tplg_vendor_array * array)627 static int sof_parse_string_tokens(struct snd_soc_component *scomp,
628 void *object, int offset,
629 const struct sof_topology_token *tokens, int num_tokens,
630 struct snd_soc_tplg_vendor_array *array)
631 {
632 struct snd_soc_tplg_vendor_string_elem *elem;
633 int found = 0;
634 int i, j, ret;
635
636 /* parse element by element */
637 for (i = 0; i < le32_to_cpu(array->num_elems); i++) {
638 elem = &array->string[i];
639
640 /* search for token */
641 for (j = 0; j < num_tokens; j++) {
642 /* match token type */
643 if (tokens[j].type != SND_SOC_TPLG_TUPLE_TYPE_STRING)
644 continue;
645
646 /* match token id */
647 if (tokens[j].token != le32_to_cpu(elem->token))
648 continue;
649
650 /* matched - now load token */
651 ret = tokens[j].get_token(elem->string, object, offset + tokens[j].offset);
652 if (ret < 0)
653 return ret;
654
655 found++;
656 }
657 }
658
659 return found;
660 }
661
662 /**
663 * sof_parse_word_tokens - Parse multiple sets of tokens
664 * @scomp: pointer to soc component
665 * @object: target ipc struct for parsed values
666 * @offset: offset within the object pointer
667 * @tokens: array of struct sof_topology_token containing the tokens to be matched
668 * @num_tokens: number of tokens in tokens array
669 * @array: source pointer to consecutive vendor arrays in topology
670 *
671 * This function parses multiple sets of word type tokens in vendor arrays
672 */
sof_parse_word_tokens(struct snd_soc_component * scomp,void * object,int offset,const struct sof_topology_token * tokens,int num_tokens,struct snd_soc_tplg_vendor_array * array)673 static int sof_parse_word_tokens(struct snd_soc_component *scomp,
674 void *object, int offset,
675 const struct sof_topology_token *tokens, int num_tokens,
676 struct snd_soc_tplg_vendor_array *array)
677 {
678 struct snd_soc_tplg_vendor_value_elem *elem;
679 int found = 0;
680 int i, j;
681
682 /* parse element by element */
683 for (i = 0; i < le32_to_cpu(array->num_elems); i++) {
684 elem = &array->value[i];
685
686 /* search for token */
687 for (j = 0; j < num_tokens; j++) {
688 /* match token type */
689 if (!(tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_WORD ||
690 tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_SHORT ||
691 tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_BYTE ||
692 tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_BOOL))
693 continue;
694
695 /* match token id */
696 if (tokens[j].token != le32_to_cpu(elem->token))
697 continue;
698
699 /* load token */
700 tokens[j].get_token(elem, object, offset + tokens[j].offset);
701
702 found++;
703 }
704 }
705
706 return found;
707 }
708
709 /**
710 * sof_parse_token_sets - Parse multiple sets of tokens
711 * @scomp: pointer to soc component
712 * @object: target ipc struct for parsed values
713 * @tokens: token definition array describing what tokens to parse
714 * @count: number of tokens in definition array
715 * @array: source pointer to consecutive vendor arrays in topology
716 * @array_size: total size of @array
717 * @token_instance_num: number of times the same tokens needs to be parsed i.e. the function
718 * looks for @token_instance_num of each token in the @tokens
719 * @object_size: offset to next target ipc struct with multiple sets
720 *
721 * This function parses multiple sets of tokens in vendor arrays into
722 * consecutive ipc structs.
723 */
sof_parse_token_sets(struct snd_soc_component * scomp,void * object,const struct sof_topology_token * tokens,int count,struct snd_soc_tplg_vendor_array * array,int array_size,int token_instance_num,size_t object_size)724 static int sof_parse_token_sets(struct snd_soc_component *scomp,
725 void *object, const struct sof_topology_token *tokens,
726 int count, struct snd_soc_tplg_vendor_array *array,
727 int array_size, int token_instance_num, size_t object_size)
728 {
729 size_t offset = 0;
730 int found = 0;
731 int total = 0;
732 int asize;
733 int ret;
734
735 while (array_size > 0 && total < count * token_instance_num) {
736 asize = le32_to_cpu(array->size);
737
738 /* validate asize */
739 if (asize < sizeof(*array)) {
740 dev_err(scomp->dev, "error: invalid array size 0x%x\n",
741 asize);
742 return -EINVAL;
743 }
744
745 /* make sure there is enough data before parsing */
746 array_size -= asize;
747 if (array_size < 0) {
748 dev_err(scomp->dev, "error: invalid array size 0x%x\n",
749 asize);
750 return -EINVAL;
751 }
752
753 /* call correct parser depending on type */
754 switch (le32_to_cpu(array->type)) {
755 case SND_SOC_TPLG_TUPLE_TYPE_UUID:
756 found += sof_parse_uuid_tokens(scomp, object, offset, tokens, count,
757 array);
758 break;
759 case SND_SOC_TPLG_TUPLE_TYPE_STRING:
760
761 ret = sof_parse_string_tokens(scomp, object, offset, tokens, count,
762 array);
763 if (ret < 0) {
764 dev_err(scomp->dev, "error: no memory to copy string token\n");
765 return ret;
766 }
767
768 found += ret;
769 break;
770 case SND_SOC_TPLG_TUPLE_TYPE_BOOL:
771 case SND_SOC_TPLG_TUPLE_TYPE_BYTE:
772 case SND_SOC_TPLG_TUPLE_TYPE_WORD:
773 case SND_SOC_TPLG_TUPLE_TYPE_SHORT:
774 found += sof_parse_word_tokens(scomp, object, offset, tokens, count,
775 array);
776 break;
777 default:
778 dev_err(scomp->dev, "error: unknown token type %u\n",
779 le32_to_cpu(array->type));
780 return -EINVAL;
781 }
782
783 /* next array */
784 array = (struct snd_soc_tplg_vendor_array *)((u8 *)array
785 + asize);
786
787 /* move to next target struct */
788 if (found >= count) {
789 offset += object_size;
790 total += found;
791 found = 0;
792 }
793 }
794
795 return 0;
796 }
797
798 /**
799 * sof_parse_tokens - Parse one set of tokens
800 * @scomp: pointer to soc component
801 * @object: target ipc struct for parsed values
802 * @tokens: token definition array describing what tokens to parse
803 * @num_tokens: number of tokens in definition array
804 * @array: source pointer to consecutive vendor arrays in topology
805 * @array_size: total size of @array
806 *
807 * This function parses a single set of tokens in vendor arrays into
808 * consecutive ipc structs.
809 */
sof_parse_tokens(struct snd_soc_component * scomp,void * object,const struct sof_topology_token * tokens,int num_tokens,struct snd_soc_tplg_vendor_array * array,int array_size)810 static int sof_parse_tokens(struct snd_soc_component *scomp, void *object,
811 const struct sof_topology_token *tokens, int num_tokens,
812 struct snd_soc_tplg_vendor_array *array,
813 int array_size)
814
815 {
816 /*
817 * sof_parse_tokens is used when topology contains only a single set of
818 * identical tuples arrays. So additional parameters to
819 * sof_parse_token_sets are sets = 1 (only 1 set) and
820 * object_size = 0 (irrelevant).
821 */
822 return sof_parse_token_sets(scomp, object, tokens, num_tokens, array,
823 array_size, 1, 0);
824 }
825
826 /*
827 * Standard Kcontrols.
828 */
829
sof_control_load_volume(struct snd_soc_component * scomp,struct snd_sof_control * scontrol,struct snd_kcontrol_new * kc,struct snd_soc_tplg_ctl_hdr * hdr)830 static int sof_control_load_volume(struct snd_soc_component *scomp,
831 struct snd_sof_control *scontrol,
832 struct snd_kcontrol_new *kc,
833 struct snd_soc_tplg_ctl_hdr *hdr)
834 {
835 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
836 struct snd_soc_tplg_mixer_control *mc =
837 container_of(hdr, struct snd_soc_tplg_mixer_control, hdr);
838 int tlv[SOF_TLV_ITEMS];
839 unsigned int mask;
840 int ret;
841
842 /* validate topology data */
843 if (le32_to_cpu(mc->num_channels) > SND_SOC_TPLG_MAX_CHAN)
844 return -EINVAL;
845
846 /*
847 * If control has more than 2 channels we need to override the info. This is because even if
848 * ASoC layer has defined topology's max channel count to SND_SOC_TPLG_MAX_CHAN = 8, the
849 * pre-defined dapm control types (and related functions) creating the actual control
850 * restrict the channels only to mono or stereo.
851 */
852 if (le32_to_cpu(mc->num_channels) > 2)
853 kc->info = snd_sof_volume_info;
854
855 scontrol->comp_id = sdev->next_comp_id;
856 scontrol->min_volume_step = le32_to_cpu(mc->min);
857 scontrol->max_volume_step = le32_to_cpu(mc->max);
858 scontrol->num_channels = le32_to_cpu(mc->num_channels);
859
860 scontrol->max = le32_to_cpu(mc->max);
861 if (le32_to_cpu(mc->max) == 1)
862 goto skip;
863
864 /* extract tlv data */
865 if (!kc->tlv.p || get_tlv_data(kc->tlv.p, tlv) < 0) {
866 dev_err(scomp->dev, "error: invalid TLV data\n");
867 return -EINVAL;
868 }
869
870 /* set up volume table */
871 ret = set_up_volume_table(scontrol, tlv, le32_to_cpu(mc->max) + 1);
872 if (ret < 0) {
873 dev_err(scomp->dev, "error: setting up volume table\n");
874 return ret;
875 }
876
877 skip:
878 /* set up possible led control from mixer private data */
879 ret = sof_parse_tokens(scomp, &scontrol->led_ctl, led_tokens,
880 ARRAY_SIZE(led_tokens), mc->priv.array,
881 le32_to_cpu(mc->priv.size));
882 if (ret != 0) {
883 dev_err(scomp->dev, "error: parse led tokens failed %u\n",
884 le32_to_cpu(mc->priv.size));
885 goto err;
886 }
887
888 if (scontrol->led_ctl.use_led) {
889 mask = scontrol->led_ctl.direction ? SNDRV_CTL_ELEM_ACCESS_MIC_LED :
890 SNDRV_CTL_ELEM_ACCESS_SPK_LED;
891 scontrol->access &= ~SNDRV_CTL_ELEM_ACCESS_LED_MASK;
892 scontrol->access |= mask;
893 kc->access &= ~SNDRV_CTL_ELEM_ACCESS_LED_MASK;
894 kc->access |= mask;
895 sdev->led_present = true;
896 }
897
898 dev_dbg(scomp->dev, "tplg: load kcontrol index %d chans %d\n",
899 scontrol->comp_id, scontrol->num_channels);
900
901 return 0;
902
903 err:
904 if (le32_to_cpu(mc->max) > 1)
905 kfree(scontrol->volume_table);
906
907 return ret;
908 }
909
sof_control_load_enum(struct snd_soc_component * scomp,struct snd_sof_control * scontrol,struct snd_kcontrol_new * kc,struct snd_soc_tplg_ctl_hdr * hdr)910 static int sof_control_load_enum(struct snd_soc_component *scomp,
911 struct snd_sof_control *scontrol,
912 struct snd_kcontrol_new *kc,
913 struct snd_soc_tplg_ctl_hdr *hdr)
914 {
915 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
916 struct snd_soc_tplg_enum_control *ec =
917 container_of(hdr, struct snd_soc_tplg_enum_control, hdr);
918
919 /* validate topology data */
920 if (le32_to_cpu(ec->num_channels) > SND_SOC_TPLG_MAX_CHAN)
921 return -EINVAL;
922
923 scontrol->comp_id = sdev->next_comp_id;
924 scontrol->num_channels = le32_to_cpu(ec->num_channels);
925
926 dev_dbg(scomp->dev, "tplg: load kcontrol index %d chans %d comp_id %d\n",
927 scontrol->comp_id, scontrol->num_channels, scontrol->comp_id);
928
929 return 0;
930 }
931
sof_control_load_bytes(struct snd_soc_component * scomp,struct snd_sof_control * scontrol,struct snd_kcontrol_new * kc,struct snd_soc_tplg_ctl_hdr * hdr)932 static int sof_control_load_bytes(struct snd_soc_component *scomp,
933 struct snd_sof_control *scontrol,
934 struct snd_kcontrol_new *kc,
935 struct snd_soc_tplg_ctl_hdr *hdr)
936 {
937 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
938 struct snd_soc_tplg_bytes_control *control =
939 container_of(hdr, struct snd_soc_tplg_bytes_control, hdr);
940 struct soc_bytes_ext *sbe = (struct soc_bytes_ext *)kc->private_value;
941 size_t priv_size = le32_to_cpu(control->priv.size);
942
943 scontrol->max_size = sbe->max;
944 scontrol->comp_id = sdev->next_comp_id;
945
946 dev_dbg(scomp->dev, "tplg: load kcontrol index %d\n", scontrol->comp_id);
947
948 /* copy the private data */
949 if (priv_size > 0) {
950 scontrol->priv = kmemdup(control->priv.data, priv_size, GFP_KERNEL);
951 if (!scontrol->priv)
952 return -ENOMEM;
953
954 scontrol->priv_size = priv_size;
955 }
956
957 return 0;
958 }
959
960 /* external kcontrol init - used for any driver specific init */
sof_control_load(struct snd_soc_component * scomp,int index,struct snd_kcontrol_new * kc,struct snd_soc_tplg_ctl_hdr * hdr)961 static int sof_control_load(struct snd_soc_component *scomp, int index,
962 struct snd_kcontrol_new *kc,
963 struct snd_soc_tplg_ctl_hdr *hdr)
964 {
965 struct soc_mixer_control *sm;
966 struct soc_bytes_ext *sbe;
967 struct soc_enum *se;
968 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
969 struct snd_soc_dobj *dobj;
970 struct snd_sof_control *scontrol;
971 int ret;
972
973 dev_dbg(scomp->dev, "tplg: load control type %u name : %s\n",
974 le32_to_cpu(hdr->type), hdr->name);
975
976 scontrol = kzalloc_obj(*scontrol);
977 if (!scontrol)
978 return -ENOMEM;
979
980 scontrol->name = kstrdup(hdr->name, GFP_KERNEL);
981 if (!scontrol->name) {
982 kfree(scontrol);
983 return -ENOMEM;
984 }
985
986 scontrol->scomp = scomp;
987 scontrol->access = kc->access;
988 scontrol->info_type = le32_to_cpu(hdr->ops.info);
989 scontrol->index = kc->index;
990
991 switch (le32_to_cpu(hdr->ops.info)) {
992 case SND_SOC_TPLG_CTL_VOLSW:
993 case SND_SOC_TPLG_CTL_VOLSW_SX:
994 case SND_SOC_TPLG_CTL_VOLSW_XR_SX:
995 sm = (struct soc_mixer_control *)kc->private_value;
996 dobj = &sm->dobj;
997 ret = sof_control_load_volume(scomp, scontrol, kc, hdr);
998 break;
999 case SND_SOC_TPLG_CTL_BYTES:
1000 sbe = (struct soc_bytes_ext *)kc->private_value;
1001 dobj = &sbe->dobj;
1002 ret = sof_control_load_bytes(scomp, scontrol, kc, hdr);
1003 break;
1004 case SND_SOC_TPLG_CTL_ENUM:
1005 case SND_SOC_TPLG_CTL_ENUM_VALUE:
1006 se = (struct soc_enum *)kc->private_value;
1007 dobj = &se->dobj;
1008 ret = sof_control_load_enum(scomp, scontrol, kc, hdr);
1009 break;
1010 case SND_SOC_TPLG_CTL_RANGE:
1011 case SND_SOC_TPLG_CTL_STROBE:
1012 case SND_SOC_TPLG_DAPM_CTL_VOLSW:
1013 case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE:
1014 case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT:
1015 case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE:
1016 case SND_SOC_TPLG_DAPM_CTL_PIN:
1017 default:
1018 dev_warn(scomp->dev, "control type not supported %u:%u:%u\n",
1019 le32_to_cpu(hdr->ops.get),
1020 le32_to_cpu(hdr->ops.put),
1021 le32_to_cpu(hdr->ops.info));
1022 kfree(scontrol->name);
1023 kfree(scontrol);
1024 return 0;
1025 }
1026
1027 if (ret < 0) {
1028 kfree(scontrol->name);
1029 kfree(scontrol);
1030 return ret;
1031 }
1032
1033 scontrol->led_ctl.led_value = -1;
1034
1035 dobj->private = scontrol;
1036 list_add(&scontrol->list, &sdev->kcontrol_list);
1037 return 0;
1038 }
1039
sof_control_unload(struct snd_soc_component * scomp,struct snd_soc_dobj * dobj)1040 static int sof_control_unload(struct snd_soc_component *scomp,
1041 struct snd_soc_dobj *dobj)
1042 {
1043 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1044 const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
1045 struct snd_sof_control *scontrol = dobj->private;
1046 int ret = 0;
1047
1048 dev_dbg(scomp->dev, "tplg: unload control name : %s\n", scontrol->name);
1049
1050 if (tplg_ops && tplg_ops->control_free) {
1051 ret = tplg_ops->control_free(sdev, scontrol);
1052 if (ret < 0)
1053 dev_err(scomp->dev, "failed to free control: %s\n", scontrol->name);
1054 }
1055
1056 /* free all data before returning in case of error too */
1057 kfree(scontrol->ipc_control_data);
1058 kfree(scontrol->priv);
1059 kfree(scontrol->name);
1060 list_del(&scontrol->list);
1061 kfree(scontrol);
1062
1063 return ret;
1064 }
1065
1066 /*
1067 * DAI Topology
1068 */
1069
sof_connect_dai_widget(struct snd_soc_component * scomp,struct snd_soc_dapm_widget * w,struct snd_soc_tplg_dapm_widget * tw,struct snd_sof_dai * dai)1070 static int sof_connect_dai_widget(struct snd_soc_component *scomp,
1071 struct snd_soc_dapm_widget *w,
1072 struct snd_soc_tplg_dapm_widget *tw,
1073 struct snd_sof_dai *dai)
1074 {
1075 struct snd_soc_card *card = scomp->card;
1076 struct snd_soc_pcm_runtime *rtd, *full, *partial;
1077 struct snd_soc_dai *cpu_dai;
1078 int stream;
1079 int i;
1080
1081 if (!w->sname) {
1082 dev_err(scomp->dev, "Widget %s does not have stream\n", w->name);
1083 return -EINVAL;
1084 }
1085
1086 if (w->id == snd_soc_dapm_dai_out)
1087 stream = SNDRV_PCM_STREAM_CAPTURE;
1088 else if (w->id == snd_soc_dapm_dai_in)
1089 stream = SNDRV_PCM_STREAM_PLAYBACK;
1090 else
1091 goto end;
1092
1093 full = NULL;
1094 partial = NULL;
1095 list_for_each_entry(rtd, &card->rtd_list, list) {
1096 /* does stream match DAI link ? */
1097 if (rtd->dai_link->stream_name) {
1098 if (!strcmp(rtd->dai_link->stream_name, w->sname)) {
1099 full = rtd;
1100 break;
1101 } else if (strstr(rtd->dai_link->stream_name, w->sname)) {
1102 partial = rtd;
1103 }
1104 }
1105 }
1106
1107 rtd = full ? full : partial;
1108 if (rtd) {
1109 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
1110 /*
1111 * Please create DAI widget in the right order
1112 * to ensure BE will connect to the right DAI
1113 * widget.
1114 */
1115 if (!snd_soc_dai_get_widget(cpu_dai, stream)) {
1116 snd_soc_dai_set_widget(cpu_dai, stream, w);
1117 break;
1118 }
1119 }
1120 if (i == rtd->dai_link->num_cpus) {
1121 dev_err(scomp->dev, "error: can't find BE for DAI %s\n", w->name);
1122
1123 return -EINVAL;
1124 }
1125
1126 dai->name = rtd->dai_link->name;
1127 dev_dbg(scomp->dev, "tplg: connected widget %s -> DAI link %s\n",
1128 w->name, rtd->dai_link->name);
1129 }
1130 end:
1131 /* check we have a connection */
1132 if (!dai->name) {
1133 dev_err(scomp->dev, "error: can't connect DAI %s stream %s\n",
1134 w->name, w->sname);
1135 return -EINVAL;
1136 }
1137
1138 return 0;
1139 }
1140
sof_disconnect_dai_widget(struct snd_soc_component * scomp,struct snd_soc_dapm_widget * w)1141 static void sof_disconnect_dai_widget(struct snd_soc_component *scomp,
1142 struct snd_soc_dapm_widget *w)
1143 {
1144 struct snd_soc_card *card = scomp->card;
1145 struct snd_soc_pcm_runtime *rtd;
1146 const char *sname = w->sname;
1147 struct snd_soc_dai *cpu_dai;
1148 int i, stream;
1149
1150 if (!sname)
1151 return;
1152
1153 if (w->id == snd_soc_dapm_dai_out)
1154 stream = SNDRV_PCM_STREAM_CAPTURE;
1155 else if (w->id == snd_soc_dapm_dai_in)
1156 stream = SNDRV_PCM_STREAM_PLAYBACK;
1157 else
1158 return;
1159
1160 list_for_each_entry(rtd, &card->rtd_list, list) {
1161 /* does stream match DAI link ? */
1162 if (!rtd->dai_link->stream_name ||
1163 !strstr(rtd->dai_link->stream_name, sname))
1164 continue;
1165
1166 for_each_rtd_cpu_dais(rtd, i, cpu_dai)
1167 if (snd_soc_dai_get_widget(cpu_dai, stream) == w) {
1168 snd_soc_dai_set_widget(cpu_dai, stream, NULL);
1169 break;
1170 }
1171 }
1172 }
1173
1174 /* bind PCM ID to host component ID */
spcm_bind(struct snd_soc_component * scomp,struct snd_sof_pcm * spcm,int dir)1175 static int spcm_bind(struct snd_soc_component *scomp, struct snd_sof_pcm *spcm,
1176 int dir)
1177 {
1178 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1179 struct snd_sof_widget *host_widget;
1180
1181 if (sdev->dspless_mode_selected)
1182 return 0;
1183
1184 host_widget = snd_sof_find_swidget_sname(scomp,
1185 spcm->pcm.caps[dir].name,
1186 dir);
1187 if (!host_widget) {
1188 dev_err(scomp->dev, "can't find host comp to bind pcm\n");
1189 return -EINVAL;
1190 }
1191
1192 spcm->stream[dir].comp_id = host_widget->comp_id;
1193
1194 return 0;
1195 }
1196
sof_get_token_value(u32 token_id,struct snd_sof_tuple * tuples,int num_tuples)1197 static int sof_get_token_value(u32 token_id, struct snd_sof_tuple *tuples, int num_tuples)
1198 {
1199 int i;
1200
1201 if (!tuples)
1202 return -EINVAL;
1203
1204 for (i = 0; i < num_tuples; i++) {
1205 if (tuples[i].token == token_id)
1206 return tuples[i].value.v;
1207 }
1208
1209 return -EINVAL;
1210 }
1211
sof_widget_parse_tokens(struct snd_soc_component * scomp,struct snd_sof_widget * swidget,struct snd_soc_tplg_dapm_widget * tw,enum sof_tokens * object_token_list,int count)1212 static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_sof_widget *swidget,
1213 struct snd_soc_tplg_dapm_widget *tw,
1214 enum sof_tokens *object_token_list, int count)
1215 {
1216 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1217 const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
1218 struct snd_soc_tplg_private *private = &tw->priv;
1219 const struct sof_token_info *token_list;
1220 int num_tuples = 0;
1221 int ret, i;
1222
1223 token_list = tplg_ops ? tplg_ops->token_list : NULL;
1224 /* nothing to do if token_list is NULL */
1225 if (!token_list)
1226 return 0;
1227
1228 if (count > 0 && !object_token_list) {
1229 dev_err(scomp->dev, "No token list for widget %s\n", swidget->widget->name);
1230 return -EINVAL;
1231 }
1232
1233 /* calculate max size of tuples array */
1234 for (i = 0; i < count; i++)
1235 num_tuples += token_list[object_token_list[i]].count;
1236
1237 /* allocate memory for tuples array */
1238 swidget->tuples = kzalloc_objs(*swidget->tuples, num_tuples);
1239 if (!swidget->tuples)
1240 return -ENOMEM;
1241
1242 /* parse token list for widget */
1243 for (i = 0; i < count; i++) {
1244 int num_sets = 1;
1245
1246 if (object_token_list[i] >= SOF_TOKEN_COUNT) {
1247 dev_err(scomp->dev, "Invalid token id %d for widget %s\n",
1248 object_token_list[i], swidget->widget->name);
1249 ret = -EINVAL;
1250 goto err;
1251 }
1252
1253 switch (object_token_list[i]) {
1254 case SOF_COMP_EXT_TOKENS:
1255 /* parse and save UUID in swidget */
1256 ret = sof_parse_tokens(scomp, swidget,
1257 token_list[object_token_list[i]].tokens,
1258 token_list[object_token_list[i]].count,
1259 private->array, le32_to_cpu(private->size));
1260 if (ret < 0) {
1261 dev_err(scomp->dev, "Failed parsing %s for widget %s\n",
1262 token_list[object_token_list[i]].name,
1263 swidget->widget->name);
1264 goto err;
1265 }
1266
1267 continue;
1268 case SOF_IN_AUDIO_FORMAT_TOKENS:
1269 num_sets = sof_get_token_value(SOF_TKN_COMP_NUM_INPUT_AUDIO_FORMATS,
1270 swidget->tuples, swidget->num_tuples);
1271 if (num_sets < 0) {
1272 dev_err(sdev->dev, "Invalid input audio format count for %s\n",
1273 swidget->widget->name);
1274 ret = num_sets;
1275 goto err;
1276 }
1277 break;
1278 case SOF_OUT_AUDIO_FORMAT_TOKENS:
1279 num_sets = sof_get_token_value(SOF_TKN_COMP_NUM_OUTPUT_AUDIO_FORMATS,
1280 swidget->tuples, swidget->num_tuples);
1281 if (num_sets < 0) {
1282 dev_err(sdev->dev, "Invalid output audio format count for %s\n",
1283 swidget->widget->name);
1284 ret = num_sets;
1285 goto err;
1286 }
1287 break;
1288 default:
1289 break;
1290 }
1291
1292 if (num_sets > 1) {
1293 struct snd_sof_tuple *new_tuples;
1294
1295 num_tuples += token_list[object_token_list[i]].count * (num_sets - 1);
1296 new_tuples = krealloc_array(swidget->tuples,
1297 num_tuples, sizeof(*new_tuples), GFP_KERNEL);
1298 if (!new_tuples) {
1299 ret = -ENOMEM;
1300 goto err;
1301 }
1302
1303 swidget->tuples = new_tuples;
1304 }
1305
1306 /* copy one set of tuples per token ID into swidget->tuples */
1307 ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size),
1308 object_token_list[i], num_sets, swidget->tuples,
1309 num_tuples, &swidget->num_tuples);
1310 if (ret < 0) {
1311 dev_err(scomp->dev, "Failed parsing %s for widget %s err: %d\n",
1312 token_list[object_token_list[i]].name, swidget->widget->name, ret);
1313 goto err;
1314 }
1315 }
1316
1317 return 0;
1318 err:
1319 kfree(swidget->tuples);
1320 return ret;
1321 }
1322
sof_free_pin_binding(struct snd_sof_widget * swidget,bool pin_type)1323 static void sof_free_pin_binding(struct snd_sof_widget *swidget,
1324 bool pin_type)
1325 {
1326 char **pin_binding;
1327 u32 num_pins;
1328 int i;
1329
1330 if (pin_type == SOF_PIN_TYPE_INPUT) {
1331 pin_binding = swidget->input_pin_binding;
1332 num_pins = swidget->num_input_pins;
1333 } else {
1334 pin_binding = swidget->output_pin_binding;
1335 num_pins = swidget->num_output_pins;
1336 }
1337
1338 if (pin_binding) {
1339 for (i = 0; i < num_pins; i++)
1340 kfree(pin_binding[i]);
1341 }
1342
1343 kfree(pin_binding);
1344 }
1345
sof_parse_pin_binding(struct snd_sof_widget * swidget,struct snd_soc_tplg_private * priv,bool pin_type)1346 static int sof_parse_pin_binding(struct snd_sof_widget *swidget,
1347 struct snd_soc_tplg_private *priv, bool pin_type)
1348 {
1349 const struct sof_topology_token *pin_binding_token;
1350 char *pin_binding[SOF_WIDGET_MAX_NUM_PINS];
1351 int token_count;
1352 u32 num_pins;
1353 char **pb;
1354 int ret;
1355 int i;
1356
1357 if (pin_type == SOF_PIN_TYPE_INPUT) {
1358 num_pins = swidget->num_input_pins;
1359 pin_binding_token = comp_input_pin_binding_tokens;
1360 token_count = ARRAY_SIZE(comp_input_pin_binding_tokens);
1361 } else {
1362 num_pins = swidget->num_output_pins;
1363 pin_binding_token = comp_output_pin_binding_tokens;
1364 token_count = ARRAY_SIZE(comp_output_pin_binding_tokens);
1365 }
1366
1367 memset(pin_binding, 0, SOF_WIDGET_MAX_NUM_PINS * sizeof(char *));
1368 ret = sof_parse_token_sets(swidget->scomp, pin_binding, pin_binding_token,
1369 token_count, priv->array, le32_to_cpu(priv->size),
1370 num_pins, sizeof(char *));
1371 if (ret < 0)
1372 goto err;
1373
1374 /* copy pin binding array to swidget only if it is defined in topology */
1375 if (pin_binding[0]) {
1376 pb = kmemdup_array(pin_binding, num_pins, sizeof(char *), GFP_KERNEL);
1377 if (!pb) {
1378 ret = -ENOMEM;
1379 goto err;
1380 }
1381 if (pin_type == SOF_PIN_TYPE_INPUT)
1382 swidget->input_pin_binding = pb;
1383 else
1384 swidget->output_pin_binding = pb;
1385 }
1386
1387 return 0;
1388
1389 err:
1390 for (i = 0; i < num_pins; i++)
1391 kfree(pin_binding[i]);
1392
1393 return ret;
1394 }
1395
get_w_no_wname_in_long_name(void * elem,void * object,u32 offset)1396 static int get_w_no_wname_in_long_name(void *elem, void *object, u32 offset)
1397 {
1398 struct snd_soc_tplg_vendor_value_elem *velem = elem;
1399 struct snd_soc_dapm_widget *w = object;
1400
1401 w->no_wname_in_kcontrol_name = !!le32_to_cpu(velem->value);
1402 return 0;
1403 }
1404
1405 static const struct sof_topology_token dapm_widget_tokens[] = {
1406 {SOF_TKN_COMP_NO_WNAME_IN_KCONTROL_NAME, SND_SOC_TPLG_TUPLE_TYPE_BOOL,
1407 get_w_no_wname_in_long_name, 0}
1408 };
1409
1410 /* external widget init - used for any driver specific init */
sof_widget_ready(struct snd_soc_component * scomp,int index,struct snd_soc_dapm_widget * w,struct snd_soc_tplg_dapm_widget * tw)1411 static int sof_widget_ready(struct snd_soc_component *scomp, int index,
1412 struct snd_soc_dapm_widget *w,
1413 struct snd_soc_tplg_dapm_widget *tw)
1414 {
1415 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1416 const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
1417 const struct sof_ipc_tplg_widget_ops *widget_ops;
1418 struct snd_soc_tplg_private *priv = &tw->priv;
1419 enum sof_tokens *token_list = NULL;
1420 struct snd_sof_widget *swidget;
1421 struct snd_sof_dai *dai;
1422 int token_list_size = 0;
1423 int ret = 0;
1424
1425 swidget = kzalloc_obj(*swidget);
1426 if (!swidget)
1427 return -ENOMEM;
1428
1429 swidget->scomp = scomp;
1430 swidget->widget = w;
1431 swidget->comp_id = sdev->next_comp_id++;
1432 swidget->id = w->id;
1433 swidget->pipeline_id = index;
1434 swidget->private = NULL;
1435 mutex_init(&swidget->setup_mutex);
1436
1437 ida_init(&swidget->output_queue_ida);
1438 ida_init(&swidget->input_queue_ida);
1439
1440 ret = sof_parse_tokens(scomp, w, dapm_widget_tokens, ARRAY_SIZE(dapm_widget_tokens),
1441 priv->array, le32_to_cpu(priv->size));
1442 if (ret < 0) {
1443 dev_err(scomp->dev, "failed to parse dapm widget tokens for %s\n",
1444 w->name);
1445 goto widget_free;
1446 }
1447
1448 ret = sof_parse_tokens(scomp, swidget, comp_pin_tokens,
1449 ARRAY_SIZE(comp_pin_tokens), priv->array,
1450 le32_to_cpu(priv->size));
1451 if (ret < 0) {
1452 dev_err(scomp->dev, "failed to parse component pin tokens for %s\n",
1453 w->name);
1454 goto widget_free;
1455 }
1456
1457 if (swidget->num_input_pins > SOF_WIDGET_MAX_NUM_PINS ||
1458 swidget->num_output_pins > SOF_WIDGET_MAX_NUM_PINS) {
1459 dev_err(scomp->dev, "invalid pins for %s: [input: %d, output: %d]\n",
1460 swidget->widget->name, swidget->num_input_pins, swidget->num_output_pins);
1461 ret = -EINVAL;
1462 goto widget_free;
1463 }
1464
1465 if (swidget->num_input_pins > 1) {
1466 ret = sof_parse_pin_binding(swidget, priv, SOF_PIN_TYPE_INPUT);
1467 /* on parsing error, pin binding is not allocated, nothing to free. */
1468 if (ret < 0) {
1469 dev_err(scomp->dev, "failed to parse input pin binding for %s\n",
1470 w->name);
1471 goto widget_free;
1472 }
1473 }
1474
1475 if (swidget->num_output_pins > 1) {
1476 ret = sof_parse_pin_binding(swidget, priv, SOF_PIN_TYPE_OUTPUT);
1477 /* on parsing error, pin binding is not allocated, nothing to free. */
1478 if (ret < 0) {
1479 dev_err(scomp->dev, "failed to parse output pin binding for %s\n",
1480 w->name);
1481 goto widget_free;
1482 }
1483 }
1484
1485 dev_dbg(scomp->dev,
1486 "tplg: widget %d (%s) is ready [type: %d, pipe: %d, pins: %d / %d, stream: %s]\n",
1487 swidget->comp_id, w->name, swidget->id, index,
1488 swidget->num_input_pins, swidget->num_output_pins,
1489 strnlen(w->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0 ? w->sname : "none");
1490
1491 widget_ops = tplg_ops ? tplg_ops->widget : NULL;
1492 if (widget_ops) {
1493 token_list = widget_ops[w->id].token_list;
1494 token_list_size = widget_ops[w->id].token_list_size;
1495 }
1496
1497 /* handle any special case widgets */
1498 switch (w->id) {
1499 case snd_soc_dapm_dai_in:
1500 case snd_soc_dapm_dai_out:
1501 dai = kzalloc_obj(*dai);
1502 if (!dai) {
1503 ret = -ENOMEM;
1504 goto widget_free;
1505 }
1506
1507 ret = sof_widget_parse_tokens(scomp, swidget, tw, token_list, token_list_size);
1508 if (!ret)
1509 ret = sof_connect_dai_widget(scomp, w, tw, dai);
1510 if (ret < 0) {
1511 kfree(dai);
1512 break;
1513 }
1514 list_add(&dai->list, &sdev->dai_list);
1515 swidget->private = dai;
1516 break;
1517 case snd_soc_dapm_effect:
1518 /* check we have some tokens - we need at least process type */
1519 if (le32_to_cpu(tw->priv.size) == 0) {
1520 dev_err(scomp->dev, "error: process tokens not found\n");
1521 ret = -EINVAL;
1522 break;
1523 }
1524 ret = sof_widget_parse_tokens(scomp, swidget, tw, token_list, token_list_size);
1525 break;
1526 case snd_soc_dapm_pga:
1527 if (!le32_to_cpu(tw->num_kcontrols)) {
1528 dev_err(scomp->dev, "invalid kcontrol count %u for volume\n",
1529 le32_to_cpu(tw->num_kcontrols));
1530 ret = -EINVAL;
1531 break;
1532 }
1533
1534 fallthrough;
1535 case snd_soc_dapm_mixer:
1536 case snd_soc_dapm_buffer:
1537 case snd_soc_dapm_scheduler:
1538 case snd_soc_dapm_aif_out:
1539 case snd_soc_dapm_aif_in:
1540 case snd_soc_dapm_src:
1541 case snd_soc_dapm_asrc:
1542 case snd_soc_dapm_siggen:
1543 case snd_soc_dapm_mux:
1544 case snd_soc_dapm_demux:
1545 ret = sof_widget_parse_tokens(scomp, swidget, tw, token_list, token_list_size);
1546 break;
1547 case snd_soc_dapm_switch:
1548 case snd_soc_dapm_dai_link:
1549 case snd_soc_dapm_kcontrol:
1550 default:
1551 dev_dbg(scomp->dev, "widget type %d name %s not handled\n", swidget->id, tw->name);
1552 break;
1553 }
1554
1555 /* check token parsing reply */
1556 if (ret < 0) {
1557 dev_err(scomp->dev,
1558 "failed to add widget type %d name : %s stream %s\n",
1559 swidget->id, tw->name, strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0
1560 ? tw->sname : "none");
1561 goto widget_free;
1562 }
1563
1564 if (sof_debug_check_flag(SOF_DBG_DISABLE_MULTICORE)) {
1565 swidget->core = SOF_DSP_PRIMARY_CORE;
1566 } else {
1567 int core = sof_get_token_value(SOF_TKN_COMP_CORE_ID, swidget->tuples,
1568 swidget->num_tuples);
1569
1570 if (core >= 0)
1571 swidget->core = core;
1572 }
1573
1574 /* bind widget to external event */
1575 if (tw->event_type) {
1576 if (widget_ops && widget_ops[w->id].bind_event) {
1577 ret = widget_ops[w->id].bind_event(scomp, swidget,
1578 le16_to_cpu(tw->event_type));
1579 if (ret) {
1580 dev_err(scomp->dev, "widget event binding failed for %s\n",
1581 swidget->widget->name);
1582 goto free;
1583 }
1584 }
1585 }
1586
1587 /* create and add pipeline for scheduler type widgets */
1588 if (w->id == snd_soc_dapm_scheduler) {
1589 struct snd_sof_pipeline *spipe;
1590
1591 spipe = kzalloc_obj(*spipe);
1592 if (!spipe) {
1593 ret = -ENOMEM;
1594 goto free;
1595 }
1596
1597 spipe->pipe_widget = swidget;
1598 swidget->spipe = spipe;
1599 list_add(&spipe->list, &sdev->pipeline_list);
1600 }
1601
1602 w->dobj.private = swidget;
1603 list_add(&swidget->list, &sdev->widget_list);
1604 return ret;
1605 free:
1606 kfree(swidget->private);
1607 kfree(swidget->tuples);
1608 widget_free:
1609 kfree(swidget);
1610 return ret;
1611 }
1612
sof_route_unload(struct snd_soc_component * scomp,struct snd_soc_dobj * dobj)1613 static int sof_route_unload(struct snd_soc_component *scomp,
1614 struct snd_soc_dobj *dobj)
1615 {
1616 struct snd_sof_route *sroute;
1617
1618 sroute = dobj->private;
1619 if (!sroute)
1620 return 0;
1621
1622 /* free sroute and its private data */
1623 kfree(sroute->private);
1624 list_del(&sroute->list);
1625 kfree(sroute);
1626
1627 return 0;
1628 }
1629
sof_widget_unload(struct snd_soc_component * scomp,struct snd_soc_dobj * dobj)1630 static int sof_widget_unload(struct snd_soc_component *scomp,
1631 struct snd_soc_dobj *dobj)
1632 {
1633 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1634 const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
1635 const struct sof_ipc_tplg_widget_ops *widget_ops;
1636 const struct snd_kcontrol_new *kc;
1637 struct snd_soc_dapm_widget *widget;
1638 struct snd_sof_control *scontrol;
1639 struct snd_sof_widget *swidget;
1640 struct soc_mixer_control *sm;
1641 struct soc_bytes_ext *sbe;
1642 struct snd_sof_dai *dai;
1643 struct soc_enum *se;
1644 int i;
1645
1646 swidget = dobj->private;
1647 if (!swidget)
1648 return 0;
1649
1650 widget = swidget->widget;
1651
1652 switch (swidget->id) {
1653 case snd_soc_dapm_dai_in:
1654 case snd_soc_dapm_dai_out:
1655 dai = swidget->private;
1656
1657 if (dai)
1658 list_del(&dai->list);
1659
1660 sof_disconnect_dai_widget(scomp, widget);
1661
1662 break;
1663 case snd_soc_dapm_scheduler:
1664 {
1665 struct snd_sof_pipeline *spipe = swidget->spipe;
1666
1667 list_del(&spipe->list);
1668 kfree(spipe);
1669 swidget->spipe = NULL;
1670 break;
1671 }
1672 default:
1673 break;
1674 }
1675 for (i = 0; i < widget->num_kcontrols; i++) {
1676 kc = &widget->kcontrol_news[i];
1677 switch (widget->dobj.widget.kcontrol_type[i]) {
1678 case SND_SOC_TPLG_TYPE_MIXER:
1679 sm = (struct soc_mixer_control *)kc->private_value;
1680 scontrol = sm->dobj.private;
1681 if (sm->max > 1)
1682 kfree(scontrol->volume_table);
1683 break;
1684 case SND_SOC_TPLG_TYPE_ENUM:
1685 se = (struct soc_enum *)kc->private_value;
1686 scontrol = se->dobj.private;
1687 break;
1688 case SND_SOC_TPLG_TYPE_BYTES:
1689 sbe = (struct soc_bytes_ext *)kc->private_value;
1690 scontrol = sbe->dobj.private;
1691 break;
1692 default:
1693 dev_warn(scomp->dev, "unsupported kcontrol_type\n");
1694 goto out;
1695 }
1696 kfree(scontrol->ipc_control_data);
1697 list_del(&scontrol->list);
1698 kfree(scontrol->name);
1699 kfree(scontrol);
1700 }
1701
1702 out:
1703 /* free IPC related data */
1704 widget_ops = tplg_ops ? tplg_ops->widget : NULL;
1705 if (widget_ops && widget_ops[swidget->id].ipc_free)
1706 widget_ops[swidget->id].ipc_free(swidget);
1707
1708 ida_destroy(&swidget->output_queue_ida);
1709 ida_destroy(&swidget->input_queue_ida);
1710
1711 sof_free_pin_binding(swidget, SOF_PIN_TYPE_INPUT);
1712 sof_free_pin_binding(swidget, SOF_PIN_TYPE_OUTPUT);
1713
1714 kfree(swidget->tuples);
1715
1716 /* remove and free swidget object */
1717 list_del(&swidget->list);
1718 kfree(swidget);
1719
1720 return 0;
1721 }
1722
1723 /*
1724 * DAI HW configuration.
1725 */
1726
1727 /* FE DAI - used for any driver specific init */
sof_dai_load(struct snd_soc_component * scomp,int index,struct snd_soc_dai_driver * dai_drv,struct snd_soc_tplg_pcm * pcm,struct snd_soc_dai * dai)1728 static int sof_dai_load(struct snd_soc_component *scomp, int index,
1729 struct snd_soc_dai_driver *dai_drv,
1730 struct snd_soc_tplg_pcm *pcm, struct snd_soc_dai *dai)
1731 {
1732 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1733 const struct sof_ipc_pcm_ops *ipc_pcm_ops = sof_ipc_get_ops(sdev, pcm);
1734 struct snd_soc_tplg_stream_caps *caps;
1735 struct snd_soc_tplg_private *private = &pcm->priv;
1736 struct snd_sof_pcm *spcm;
1737 int stream;
1738 int ret;
1739
1740 /* nothing to do for BEs atm */
1741 if (!pcm)
1742 return 0;
1743
1744 spcm = kzalloc_obj(*spcm);
1745 if (!spcm)
1746 return -ENOMEM;
1747
1748 spcm->scomp = scomp;
1749
1750 for_each_pcm_streams(stream) {
1751 spcm->stream[stream].comp_id = COMP_ID_UNASSIGNED;
1752 if (pcm->compress)
1753 snd_sof_compr_init_elapsed_work(&spcm->stream[stream].period_elapsed_work);
1754 else
1755 snd_sof_pcm_init_elapsed_work(&spcm->stream[stream].period_elapsed_work);
1756 }
1757
1758 spcm->pcm = *pcm;
1759 dev_dbg(scomp->dev, "tplg: load pcm %s\n", pcm->dai_name);
1760
1761 /* perform pcm set op */
1762 if (ipc_pcm_ops && ipc_pcm_ops->pcm_setup) {
1763 ret = ipc_pcm_ops->pcm_setup(sdev, spcm);
1764 if (ret < 0) {
1765 kfree(spcm);
1766 return ret;
1767 }
1768 }
1769
1770 dai_drv->dobj.private = spcm;
1771 list_add(&spcm->list, &sdev->pcm_list);
1772
1773 ret = sof_parse_tokens(scomp, spcm, stream_tokens,
1774 ARRAY_SIZE(stream_tokens), private->array,
1775 le32_to_cpu(private->size));
1776 if (ret) {
1777 dev_err(scomp->dev, "error: parse stream tokens failed %u\n",
1778 le32_to_cpu(private->size));
1779 return ret;
1780 }
1781
1782 /* do we need to allocate playback PCM DMA pages */
1783 if (!spcm->pcm.playback)
1784 goto capture;
1785
1786 stream = SNDRV_PCM_STREAM_PLAYBACK;
1787
1788 caps = &spcm->pcm.caps[stream];
1789
1790 /* allocate playback page table buffer */
1791 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev,
1792 PAGE_SIZE, &spcm->stream[stream].page_table);
1793 if (ret < 0) {
1794 dev_err(scomp->dev, "error: can't alloc page table for %s %d\n",
1795 caps->name, ret);
1796
1797 return ret;
1798 }
1799
1800 /* bind pcm to host comp */
1801 ret = spcm_bind(scomp, spcm, stream);
1802 if (ret) {
1803 dev_err(scomp->dev,
1804 "error: can't bind pcm to host\n");
1805 goto free_playback_tables;
1806 }
1807
1808 capture:
1809 stream = SNDRV_PCM_STREAM_CAPTURE;
1810
1811 /* do we need to allocate capture PCM DMA pages */
1812 if (!spcm->pcm.capture)
1813 return ret;
1814
1815 caps = &spcm->pcm.caps[stream];
1816
1817 /* allocate capture page table buffer */
1818 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev,
1819 PAGE_SIZE, &spcm->stream[stream].page_table);
1820 if (ret < 0) {
1821 dev_err(scomp->dev, "error: can't alloc page table for %s %d\n",
1822 caps->name, ret);
1823 goto free_playback_tables;
1824 }
1825
1826 /* bind pcm to host comp */
1827 ret = spcm_bind(scomp, spcm, stream);
1828 if (ret) {
1829 dev_err(scomp->dev,
1830 "error: can't bind pcm to host\n");
1831 snd_dma_free_pages(&spcm->stream[stream].page_table);
1832 goto free_playback_tables;
1833 }
1834
1835 return ret;
1836
1837 free_playback_tables:
1838 if (spcm->pcm.playback)
1839 snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_PLAYBACK].page_table);
1840
1841 return ret;
1842 }
1843
sof_dai_unload(struct snd_soc_component * scomp,struct snd_soc_dobj * dobj)1844 static int sof_dai_unload(struct snd_soc_component *scomp,
1845 struct snd_soc_dobj *dobj)
1846 {
1847 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1848 const struct sof_ipc_pcm_ops *ipc_pcm_ops = sof_ipc_get_ops(sdev, pcm);
1849 struct snd_sof_pcm *spcm = dobj->private;
1850
1851 /* free PCM DMA pages */
1852 if (spcm->pcm.playback)
1853 snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_PLAYBACK].page_table);
1854
1855 if (spcm->pcm.capture)
1856 snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_CAPTURE].page_table);
1857
1858 /* perform pcm free op */
1859 if (ipc_pcm_ops && ipc_pcm_ops->pcm_free)
1860 ipc_pcm_ops->pcm_free(sdev, spcm);
1861
1862 /* remove from list and free spcm */
1863 list_del(&spcm->list);
1864 kfree(spcm);
1865
1866 return 0;
1867 }
1868
1869 static const struct sof_topology_token common_dai_link_tokens[] = {
1870 {SOF_TKN_DAI_TYPE, SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_dai_type,
1871 offsetof(struct snd_sof_dai_link, type)},
1872 };
1873
1874 /* DAI link - used for any driver specific init */
sof_link_load(struct snd_soc_component * scomp,int index,struct snd_soc_dai_link * link,struct snd_soc_tplg_link_config * cfg)1875 static int sof_link_load(struct snd_soc_component *scomp, int index, struct snd_soc_dai_link *link,
1876 struct snd_soc_tplg_link_config *cfg)
1877 {
1878 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1879 const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
1880 struct snd_soc_tplg_private *private = &cfg->priv;
1881 const struct sof_token_info *token_list;
1882 struct snd_sof_dai_link *slink;
1883 u32 token_id = 0;
1884 int num_tuples = 0;
1885 int ret, num_sets;
1886
1887 if (!link->platforms) {
1888 dev_err(scomp->dev, "error: no platforms\n");
1889 return -EINVAL;
1890 }
1891 link->platforms->name = dev_name(scomp->dev);
1892
1893 if (tplg_ops && tplg_ops->link_setup) {
1894 ret = tplg_ops->link_setup(sdev, link);
1895 if (ret < 0)
1896 return ret;
1897 }
1898
1899 /* Set nonatomic property for FE dai links as their trigger action involves IPC's */
1900 if (!link->no_pcm) {
1901 link->nonatomic = true;
1902 return 0;
1903 }
1904
1905 /* check we have some tokens - we need at least DAI type */
1906 if (le32_to_cpu(private->size) == 0) {
1907 dev_err(scomp->dev, "error: expected tokens for DAI, none found\n");
1908 return -EINVAL;
1909 }
1910
1911 slink = kzalloc_flex(*slink, hw_configs, le32_to_cpu(cfg->num_hw_configs));
1912 if (!slink)
1913 return -ENOMEM;
1914
1915 slink->num_hw_configs = le32_to_cpu(cfg->num_hw_configs);
1916 memcpy(slink->hw_configs, cfg->hw_config, le32_to_cpu(cfg->num_hw_configs) * sizeof(*slink->hw_configs));
1917
1918 slink->default_hw_cfg_id = le32_to_cpu(cfg->default_hw_config_id);
1919 slink->link = link;
1920
1921 dev_dbg(scomp->dev, "tplg: %d hw_configs found, default id: %d for dai link %s!\n",
1922 slink->num_hw_configs, slink->default_hw_cfg_id, link->name);
1923
1924 ret = sof_parse_tokens(scomp, slink, common_dai_link_tokens,
1925 ARRAY_SIZE(common_dai_link_tokens),
1926 private->array, le32_to_cpu(private->size));
1927 if (ret < 0) {
1928 dev_err(scomp->dev, "Failed tp parse common DAI link tokens\n");
1929 kfree(slink);
1930 return ret;
1931 }
1932
1933 token_list = tplg_ops ? tplg_ops->token_list : NULL;
1934 if (!token_list)
1935 goto out;
1936
1937 /* calculate size of tuples array */
1938 num_tuples += token_list[SOF_DAI_LINK_TOKENS].count;
1939 num_sets = slink->num_hw_configs;
1940 switch (slink->type) {
1941 case SOF_DAI_INTEL_SSP:
1942 token_id = SOF_SSP_TOKENS;
1943 num_tuples += token_list[SOF_SSP_TOKENS].count * slink->num_hw_configs;
1944 break;
1945 case SOF_DAI_INTEL_DMIC:
1946 token_id = SOF_DMIC_TOKENS;
1947 num_tuples += token_list[SOF_DMIC_TOKENS].count;
1948
1949 /* Allocate memory for max PDM controllers */
1950 num_tuples += token_list[SOF_DMIC_PDM_TOKENS].count * SOF_DAI_INTEL_DMIC_NUM_CTRL;
1951 break;
1952 case SOF_DAI_INTEL_HDA:
1953 token_id = SOF_HDA_TOKENS;
1954 num_tuples += token_list[SOF_HDA_TOKENS].count;
1955 break;
1956 case SOF_DAI_INTEL_ALH:
1957 token_id = SOF_ALH_TOKENS;
1958 num_tuples += token_list[SOF_ALH_TOKENS].count;
1959 break;
1960 case SOF_DAI_IMX_SAI:
1961 token_id = SOF_SAI_TOKENS;
1962 num_tuples += token_list[SOF_SAI_TOKENS].count;
1963 break;
1964 case SOF_DAI_IMX_ESAI:
1965 token_id = SOF_ESAI_TOKENS;
1966 num_tuples += token_list[SOF_ESAI_TOKENS].count;
1967 break;
1968 case SOF_DAI_MEDIATEK_AFE:
1969 token_id = SOF_AFE_TOKENS;
1970 num_tuples += token_list[SOF_AFE_TOKENS].count;
1971 break;
1972 case SOF_DAI_AMD_DMIC:
1973 token_id = SOF_ACPDMIC_TOKENS;
1974 num_tuples += token_list[SOF_ACPDMIC_TOKENS].count;
1975 break;
1976 case SOF_DAI_AMD_BT:
1977 case SOF_DAI_AMD_SP:
1978 case SOF_DAI_AMD_HS:
1979 case SOF_DAI_AMD_SP_VIRTUAL:
1980 case SOF_DAI_AMD_HS_VIRTUAL:
1981 token_id = SOF_ACPI2S_TOKENS;
1982 num_tuples += token_list[SOF_ACPI2S_TOKENS].count;
1983 break;
1984 case SOF_DAI_IMX_MICFIL:
1985 token_id = SOF_MICFIL_TOKENS;
1986 num_tuples += token_list[SOF_MICFIL_TOKENS].count;
1987 break;
1988 case SOF_DAI_AMD_SDW:
1989 token_id = SOF_ACP_SDW_TOKENS;
1990 num_tuples += token_list[SOF_ACP_SDW_TOKENS].count;
1991 break;
1992 default:
1993 break;
1994 }
1995
1996 /* allocate memory for tuples array */
1997 slink->tuples = kzalloc_objs(*slink->tuples, num_tuples);
1998 if (!slink->tuples) {
1999 kfree(slink);
2000 return -ENOMEM;
2001 }
2002
2003 if (token_list[SOF_DAI_LINK_TOKENS].tokens) {
2004 /* parse one set of DAI link tokens */
2005 ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size),
2006 SOF_DAI_LINK_TOKENS, 1, slink->tuples,
2007 num_tuples, &slink->num_tuples);
2008 if (ret < 0) {
2009 dev_err(scomp->dev, "failed to parse %s for dai link %s\n",
2010 token_list[SOF_DAI_LINK_TOKENS].name, link->name);
2011 goto err;
2012 }
2013 }
2014
2015 /* nothing more to do if there are no DAI type-specific tokens defined */
2016 if (!token_id || !token_list[token_id].tokens)
2017 goto out;
2018
2019 /* parse "num_sets" sets of DAI-specific tokens */
2020 ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size),
2021 token_id, num_sets, slink->tuples, num_tuples, &slink->num_tuples);
2022 if (ret < 0) {
2023 dev_err(scomp->dev, "failed to parse %s for dai link %s\n",
2024 token_list[token_id].name, link->name);
2025 goto err;
2026 }
2027
2028 /* for DMIC, also parse all sets of DMIC PDM tokens based on active PDM count */
2029 if (token_id == SOF_DMIC_TOKENS) {
2030 num_sets = sof_get_token_value(SOF_TKN_INTEL_DMIC_NUM_PDM_ACTIVE,
2031 slink->tuples, slink->num_tuples);
2032
2033 if (num_sets < 0) {
2034 dev_err(sdev->dev, "Invalid active PDM count for %s\n", link->name);
2035 ret = num_sets;
2036 goto err;
2037 }
2038
2039 ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size),
2040 SOF_DMIC_PDM_TOKENS, num_sets, slink->tuples,
2041 num_tuples, &slink->num_tuples);
2042 if (ret < 0) {
2043 dev_err(scomp->dev, "failed to parse %s for dai link %s\n",
2044 token_list[SOF_DMIC_PDM_TOKENS].name, link->name);
2045 goto err;
2046 }
2047 }
2048 out:
2049 link->dobj.private = slink;
2050 list_add(&slink->list, &sdev->dai_link_list);
2051
2052 return 0;
2053
2054 err:
2055 kfree(slink->tuples);
2056 kfree(slink);
2057
2058 return ret;
2059 }
2060
sof_link_unload(struct snd_soc_component * scomp,struct snd_soc_dobj * dobj)2061 static int sof_link_unload(struct snd_soc_component *scomp, struct snd_soc_dobj *dobj)
2062 {
2063 struct snd_sof_dai_link *slink = dobj->private;
2064
2065 if (!slink)
2066 return 0;
2067
2068 slink->link->platforms->name = NULL;
2069
2070 kfree(slink->tuples);
2071 list_del(&slink->list);
2072 kfree(slink);
2073 dobj->private = NULL;
2074
2075 return 0;
2076 }
2077
2078 /* DAI link - used for any driver specific init */
sof_route_load(struct snd_soc_component * scomp,int index,struct snd_soc_dapm_route * route)2079 static int sof_route_load(struct snd_soc_component *scomp, int index,
2080 struct snd_soc_dapm_route *route)
2081 {
2082 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
2083 struct snd_sof_widget *source_swidget, *sink_swidget;
2084 struct snd_soc_dobj *dobj = &route->dobj;
2085 struct snd_sof_route *sroute;
2086 int ret = 0;
2087
2088 /* allocate memory for sroute and connect */
2089 sroute = kzalloc_obj(*sroute);
2090 if (!sroute)
2091 return -ENOMEM;
2092
2093 sroute->scomp = scomp;
2094 dev_dbg(scomp->dev, "sink %s control %s source %s\n",
2095 route->sink, route->control ? route->control : "none",
2096 route->source);
2097
2098 /* source component */
2099 source_swidget = snd_sof_find_swidget(scomp, (char *)route->source);
2100 if (!source_swidget) {
2101 dev_err(scomp->dev, "source %s for sink %s is not found\n",
2102 route->source, route->sink);
2103 ret = -EINVAL;
2104 goto err;
2105 }
2106
2107 /*
2108 * Virtual widgets of type output/out_drv may be added in topology
2109 * for compatibility. These are not handled by the FW.
2110 * So, don't send routes whose source/sink widget is of such types
2111 * to the DSP.
2112 */
2113 if (source_swidget->id == snd_soc_dapm_out_drv ||
2114 source_swidget->id == snd_soc_dapm_output)
2115 goto err;
2116
2117 /* sink component */
2118 sink_swidget = snd_sof_find_swidget(scomp, (char *)route->sink);
2119 if (!sink_swidget) {
2120 dev_err(scomp->dev, "sink %s for source %s is not found\n",
2121 route->sink, route->source);
2122 ret = -EINVAL;
2123 goto err;
2124 }
2125
2126 /*
2127 * Don't send routes whose sink widget is of type
2128 * output or out_drv to the DSP
2129 */
2130 if (sink_swidget->id == snd_soc_dapm_out_drv ||
2131 sink_swidget->id == snd_soc_dapm_output)
2132 goto err;
2133
2134 sroute->route = route;
2135 dobj->private = sroute;
2136 sroute->src_widget = source_swidget;
2137 sroute->sink_widget = sink_swidget;
2138
2139 /* add route to route list */
2140 list_add(&sroute->list, &sdev->route_list);
2141
2142 return 0;
2143 err:
2144 kfree(sroute);
2145 return ret;
2146 }
2147
2148 /**
2149 * sof_set_widget_pipeline - Set pipeline for a component
2150 * @sdev: pointer to struct snd_sof_dev
2151 * @spipe: pointer to struct snd_sof_pipeline
2152 * @swidget: pointer to struct snd_sof_widget that has the same pipeline ID as @pipe_widget
2153 *
2154 * Return: 0 if successful, -EINVAL on error.
2155 * The function checks if @swidget is associated with any volatile controls. If so, setting
2156 * the dynamic_pipeline_widget is disallowed.
2157 */
sof_set_widget_pipeline(struct snd_sof_dev * sdev,struct snd_sof_pipeline * spipe,struct snd_sof_widget * swidget)2158 static int sof_set_widget_pipeline(struct snd_sof_dev *sdev, struct snd_sof_pipeline *spipe,
2159 struct snd_sof_widget *swidget)
2160 {
2161 struct snd_sof_widget *pipe_widget = spipe->pipe_widget;
2162 struct snd_sof_control *scontrol;
2163
2164 if (pipe_widget->dynamic_pipeline_widget) {
2165 /* dynamic widgets cannot have volatile kcontrols */
2166 list_for_each_entry(scontrol, &sdev->kcontrol_list, list)
2167 if (scontrol->comp_id == swidget->comp_id &&
2168 (scontrol->access & SNDRV_CTL_ELEM_ACCESS_VOLATILE)) {
2169 dev_err(sdev->dev,
2170 "error: volatile control found for dynamic widget %s\n",
2171 swidget->widget->name);
2172 return -EINVAL;
2173 }
2174 }
2175
2176 /* set the pipeline and apply the dynamic_pipeline_widget_flag */
2177 swidget->spipe = spipe;
2178 swidget->dynamic_pipeline_widget = pipe_widget->dynamic_pipeline_widget;
2179
2180 return 0;
2181 }
2182
2183 /* completion - called at completion of firmware loading */
sof_complete(struct snd_soc_component * scomp)2184 static int sof_complete(struct snd_soc_component *scomp)
2185 {
2186 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
2187 const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
2188 const struct sof_ipc_tplg_widget_ops *widget_ops;
2189 struct snd_sof_control *scontrol;
2190 struct snd_sof_pipeline *spipe;
2191 int ret;
2192
2193 widget_ops = tplg_ops ? tplg_ops->widget : NULL;
2194
2195 /* first update all control IPC structures based on the IPC version */
2196 if (tplg_ops && tplg_ops->control_setup)
2197 list_for_each_entry(scontrol, &sdev->kcontrol_list, list) {
2198 ret = tplg_ops->control_setup(sdev, scontrol);
2199 if (ret < 0) {
2200 dev_err(sdev->dev, "failed updating IPC struct for control %s\n",
2201 scontrol->name);
2202 return ret;
2203 }
2204 }
2205
2206 /* set up the IPC structures for the pipeline widgets */
2207 list_for_each_entry(spipe, &sdev->pipeline_list, list) {
2208 struct snd_sof_widget *pipe_widget = spipe->pipe_widget;
2209 struct snd_sof_widget *swidget;
2210
2211 pipe_widget->instance_id = -EINVAL;
2212
2213 /* Update the scheduler widget's IPC structure */
2214 if (widget_ops && widget_ops[pipe_widget->id].ipc_setup) {
2215 ret = widget_ops[pipe_widget->id].ipc_setup(pipe_widget);
2216 if (ret < 0) {
2217 dev_err(sdev->dev, "failed updating IPC struct for %s\n",
2218 pipe_widget->widget->name);
2219 return ret;
2220 }
2221 }
2222
2223 /* set the pipeline and update the IPC structure for the non scheduler widgets */
2224 list_for_each_entry(swidget, &sdev->widget_list, list)
2225 if (swidget->widget->id != snd_soc_dapm_scheduler &&
2226 swidget->pipeline_id == pipe_widget->pipeline_id) {
2227 ret = sof_set_widget_pipeline(sdev, spipe, swidget);
2228 if (ret < 0)
2229 return ret;
2230
2231 if (widget_ops && widget_ops[swidget->id].ipc_setup) {
2232 ret = widget_ops[swidget->id].ipc_setup(swidget);
2233 if (ret < 0) {
2234 dev_err(sdev->dev,
2235 "failed updating IPC struct for %s\n",
2236 swidget->widget->name);
2237 return ret;
2238 }
2239 }
2240 }
2241 }
2242
2243 /* verify topology components loading including dynamic pipelines */
2244 if (sof_debug_check_flag(SOF_DBG_VERIFY_TPLG)) {
2245 if (tplg_ops && tplg_ops->set_up_all_pipelines &&
2246 tplg_ops->tear_down_all_pipelines) {
2247 ret = tplg_ops->set_up_all_pipelines(sdev, true);
2248 if (ret < 0) {
2249 dev_err(sdev->dev, "Failed to set up all topology pipelines: %d\n",
2250 ret);
2251 return ret;
2252 }
2253
2254 ret = tplg_ops->tear_down_all_pipelines(sdev, true);
2255 if (ret < 0) {
2256 dev_err(sdev->dev, "Failed to tear down topology pipelines: %d\n",
2257 ret);
2258 return ret;
2259 }
2260 }
2261 }
2262
2263 /* set up static pipelines */
2264 if (tplg_ops && tplg_ops->set_up_all_pipelines)
2265 return tplg_ops->set_up_all_pipelines(sdev, false);
2266
2267 return 0;
2268 }
2269
2270 /* manifest - optional to inform component of manifest */
sof_manifest(struct snd_soc_component * scomp,int index,struct snd_soc_tplg_manifest * man)2271 static int sof_manifest(struct snd_soc_component *scomp, int index,
2272 struct snd_soc_tplg_manifest *man)
2273 {
2274 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
2275 const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
2276
2277 if (tplg_ops && tplg_ops->parse_manifest)
2278 return tplg_ops->parse_manifest(scomp, index, man);
2279
2280 return 0;
2281 }
2282
2283 /* vendor specific kcontrol handlers available for binding */
2284 static const struct snd_soc_tplg_kcontrol_ops sof_io_ops[] = {
2285 {SOF_TPLG_KCTL_VOL_ID, snd_sof_volume_get, snd_sof_volume_put},
2286 {SOF_TPLG_KCTL_BYTES_ID, snd_sof_bytes_get, snd_sof_bytes_put},
2287 {SOF_TPLG_KCTL_ENUM_ID, snd_sof_enum_get, snd_sof_enum_put},
2288 {SOF_TPLG_KCTL_SWITCH_ID, snd_sof_switch_get, snd_sof_switch_put},
2289 };
2290
2291 /* vendor specific bytes ext handlers available for binding */
2292 static const struct snd_soc_tplg_bytes_ext_ops sof_bytes_ext_ops[] = {
2293 {SOF_TPLG_KCTL_BYTES_ID, snd_sof_bytes_ext_get, snd_sof_bytes_ext_put},
2294 {SOF_TPLG_KCTL_BYTES_VOLATILE_RO, snd_sof_bytes_ext_volatile_get},
2295 };
2296
2297 static const struct snd_soc_tplg_ops sof_tplg_ops = {
2298 /* external kcontrol init - used for any driver specific init */
2299 .control_load = sof_control_load,
2300 .control_unload = sof_control_unload,
2301
2302 /* external kcontrol init - used for any driver specific init */
2303 .dapm_route_load = sof_route_load,
2304 .dapm_route_unload = sof_route_unload,
2305
2306 /* external widget init - used for any driver specific init */
2307 /* .widget_load is not currently used */
2308 .widget_ready = sof_widget_ready,
2309 .widget_unload = sof_widget_unload,
2310
2311 /* FE DAI - used for any driver specific init */
2312 .dai_load = sof_dai_load,
2313 .dai_unload = sof_dai_unload,
2314
2315 /* DAI link - used for any driver specific init */
2316 .link_load = sof_link_load,
2317 .link_unload = sof_link_unload,
2318
2319 /*
2320 * No need to set the complete callback. sof_complete will be called explicitly after
2321 * topology loading is complete.
2322 */
2323
2324 /* manifest - optional to inform component of manifest */
2325 .manifest = sof_manifest,
2326
2327 /* vendor specific kcontrol handlers available for binding */
2328 .io_ops = sof_io_ops,
2329 .io_ops_count = ARRAY_SIZE(sof_io_ops),
2330
2331 /* vendor specific bytes ext handlers available for binding */
2332 .bytes_ext_ops = sof_bytes_ext_ops,
2333 .bytes_ext_ops_count = ARRAY_SIZE(sof_bytes_ext_ops),
2334 };
2335
snd_sof_dspless_kcontrol(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2336 static int snd_sof_dspless_kcontrol(struct snd_kcontrol *kcontrol,
2337 struct snd_ctl_elem_value *ucontrol)
2338 {
2339 return 0;
2340 }
2341
2342 static const struct snd_soc_tplg_kcontrol_ops sof_dspless_io_ops[] = {
2343 {SOF_TPLG_KCTL_VOL_ID, snd_sof_dspless_kcontrol, snd_sof_dspless_kcontrol},
2344 {SOF_TPLG_KCTL_BYTES_ID, snd_sof_dspless_kcontrol, snd_sof_dspless_kcontrol},
2345 {SOF_TPLG_KCTL_ENUM_ID, snd_sof_dspless_kcontrol, snd_sof_dspless_kcontrol},
2346 {SOF_TPLG_KCTL_SWITCH_ID, snd_sof_dspless_kcontrol, snd_sof_dspless_kcontrol},
2347 };
2348
snd_sof_dspless_bytes_ext_get(struct snd_kcontrol * kcontrol,unsigned int __user * binary_data,unsigned int size)2349 static int snd_sof_dspless_bytes_ext_get(struct snd_kcontrol *kcontrol,
2350 unsigned int __user *binary_data,
2351 unsigned int size)
2352 {
2353 return 0;
2354 }
2355
snd_sof_dspless_bytes_ext_put(struct snd_kcontrol * kcontrol,const unsigned int __user * binary_data,unsigned int size)2356 static int snd_sof_dspless_bytes_ext_put(struct snd_kcontrol *kcontrol,
2357 const unsigned int __user *binary_data,
2358 unsigned int size)
2359 {
2360 return 0;
2361 }
2362
2363 static const struct snd_soc_tplg_bytes_ext_ops sof_dspless_bytes_ext_ops[] = {
2364 {SOF_TPLG_KCTL_BYTES_ID, snd_sof_dspless_bytes_ext_get, snd_sof_dspless_bytes_ext_put},
2365 {SOF_TPLG_KCTL_BYTES_VOLATILE_RO, snd_sof_dspless_bytes_ext_get},
2366 };
2367
2368 /* external widget init - used for any driver specific init */
sof_dspless_widget_ready(struct snd_soc_component * scomp,int index,struct snd_soc_dapm_widget * w,struct snd_soc_tplg_dapm_widget * tw)2369 static int sof_dspless_widget_ready(struct snd_soc_component *scomp, int index,
2370 struct snd_soc_dapm_widget *w,
2371 struct snd_soc_tplg_dapm_widget *tw)
2372 {
2373 struct snd_soc_tplg_private *priv = &tw->priv;
2374 int ret;
2375
2376 /* for snd_soc_dapm_widget.no_wname_in_kcontrol_name */
2377 ret = sof_parse_tokens(scomp, w, dapm_widget_tokens,
2378 ARRAY_SIZE(dapm_widget_tokens),
2379 priv->array, le32_to_cpu(priv->size));
2380 if (ret < 0) {
2381 dev_err(scomp->dev, "failed to parse dapm widget tokens for %s\n",
2382 w->name);
2383 return ret;
2384 }
2385
2386 if (WIDGET_IS_DAI(w->id)) {
2387 static const struct sof_topology_token dai_tokens[] = {
2388 {SOF_TKN_DAI_TYPE, SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_dai_type, 0}};
2389 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
2390 struct snd_sof_widget *swidget;
2391 struct snd_sof_dai *sdai;
2392
2393 swidget = kzalloc_obj(*swidget);
2394 if (!swidget)
2395 return -ENOMEM;
2396
2397 sdai = kzalloc_obj(*sdai);
2398 if (!sdai) {
2399 kfree(swidget);
2400 return -ENOMEM;
2401 }
2402
2403 ret = sof_parse_tokens(scomp, &sdai->type, dai_tokens, ARRAY_SIZE(dai_tokens),
2404 priv->array, le32_to_cpu(priv->size));
2405 if (ret < 0) {
2406 dev_err(scomp->dev, "Failed to parse DAI tokens for %s\n", tw->name);
2407 kfree(swidget);
2408 kfree(sdai);
2409 return ret;
2410 }
2411
2412 ret = sof_connect_dai_widget(scomp, w, tw, sdai);
2413 if (ret) {
2414 kfree(swidget);
2415 kfree(sdai);
2416 return ret;
2417 }
2418
2419 swidget->scomp = scomp;
2420 swidget->widget = w;
2421 swidget->private = sdai;
2422 mutex_init(&swidget->setup_mutex);
2423 w->dobj.private = swidget;
2424 list_add(&swidget->list, &sdev->widget_list);
2425 }
2426
2427 return 0;
2428 }
2429
sof_dspless_widget_unload(struct snd_soc_component * scomp,struct snd_soc_dobj * dobj)2430 static int sof_dspless_widget_unload(struct snd_soc_component *scomp,
2431 struct snd_soc_dobj *dobj)
2432 {
2433 struct snd_soc_dapm_widget *w = container_of(dobj, struct snd_soc_dapm_widget, dobj);
2434
2435 if (WIDGET_IS_DAI(w->id)) {
2436 struct snd_sof_widget *swidget = dobj->private;
2437
2438 sof_disconnect_dai_widget(scomp, w);
2439
2440 if (!swidget)
2441 return 0;
2442
2443 /* remove and free swidget object */
2444 list_del(&swidget->list);
2445 kfree(swidget->private);
2446 kfree(swidget);
2447 }
2448
2449 return 0;
2450 }
2451
sof_dspless_link_load(struct snd_soc_component * scomp,int index,struct snd_soc_dai_link * link,struct snd_soc_tplg_link_config * cfg)2452 static int sof_dspless_link_load(struct snd_soc_component *scomp, int index,
2453 struct snd_soc_dai_link *link,
2454 struct snd_soc_tplg_link_config *cfg)
2455 {
2456 link->platforms->name = dev_name(scomp->dev);
2457
2458 /* Set nonatomic property for FE dai links for FE-BE compatibility */
2459 if (!link->no_pcm)
2460 link->nonatomic = true;
2461
2462 return 0;
2463 }
2464
2465 static const struct snd_soc_tplg_ops sof_dspless_tplg_ops = {
2466 /* external widget init - used for any driver specific init */
2467 .widget_ready = sof_dspless_widget_ready,
2468 .widget_unload = sof_dspless_widget_unload,
2469
2470 /* FE DAI - used for any driver specific init */
2471 .dai_load = sof_dai_load,
2472 .dai_unload = sof_dai_unload,
2473
2474 /* DAI link - used for any driver specific init */
2475 .link_load = sof_dspless_link_load,
2476
2477 /* vendor specific kcontrol handlers available for binding */
2478 .io_ops = sof_dspless_io_ops,
2479 .io_ops_count = ARRAY_SIZE(sof_dspless_io_ops),
2480
2481 /* vendor specific bytes ext handlers available for binding */
2482 .bytes_ext_ops = sof_dspless_bytes_ext_ops,
2483 .bytes_ext_ops_count = ARRAY_SIZE(sof_dspless_bytes_ext_ops),
2484 };
2485
snd_sof_load_topology(struct snd_soc_component * scomp,const char * file)2486 int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
2487 {
2488 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
2489 struct snd_sof_pdata *sof_pdata = sdev->pdata;
2490 const char *tplg_filename_prefix = sof_pdata->tplg_filename_prefix;
2491 const struct firmware *fw;
2492 const char **tplg_files;
2493 int tplg_cnt = 0;
2494 int ret;
2495 int i;
2496
2497 tplg_files = kcalloc(scomp->card->num_links, sizeof(char *), GFP_KERNEL);
2498 if (!tplg_files)
2499 return -ENOMEM;
2500
2501 /* Try to use function topologies if possible */
2502 if (!sof_pdata->disable_function_topology && !disable_function_topology &&
2503 sof_pdata->machine && sof_pdata->machine->get_function_tplg_files) {
2504 /*
2505 * When the topology name contains 'dummy' word, it means that
2506 * there is no fallback option to monolithic topology in case
2507 * any of the function topologies might be missing.
2508 * In this case we should use best effort to form the card,
2509 * ignoring functionalities that we are missing a fragment for.
2510 *
2511 * Note: monolithic topologies also ignore these possibly
2512 * missing functions, so the functionality of the card would be
2513 * identical to the case if there would be a fallback monolithic
2514 * topology created for the configuration.
2515 */
2516 bool no_fallback = strstr(file, "dummy");
2517
2518 tplg_cnt = sof_pdata->machine->get_function_tplg_files(scomp->card,
2519 sof_pdata->machine,
2520 tplg_filename_prefix,
2521 &tplg_files,
2522 no_fallback);
2523 if (tplg_cnt < 0) {
2524 kfree(tplg_files);
2525 return tplg_cnt;
2526 }
2527 }
2528
2529 /*
2530 * The monolithic topology will be used if there is no get_function_tplg_files
2531 * callback or the callback returns 0.
2532 */
2533 if (!tplg_cnt) {
2534 if (strstr(file, "dummy")) {
2535 dev_err(scomp->dev,
2536 "Function topology is required, please upgrade sof-firmware\n");
2537 return -EINVAL;
2538 }
2539 tplg_files[0] = file;
2540 tplg_cnt = 1;
2541 dev_info(scomp->dev, "loading topology: %s\n", file);
2542 } else {
2543 dev_info(scomp->dev, "Using function topologies instead %s\n", file);
2544 }
2545
2546 for (i = 0; i < tplg_cnt; i++) {
2547 /* Only print the file names if the function topologies are used */
2548 if (tplg_files[0] != file)
2549 dev_info(scomp->dev, "loading topology %d: %s\n", i, tplg_files[i]);
2550
2551 ret = request_firmware(&fw, tplg_files[i], scomp->dev);
2552 if (ret < 0) {
2553 /*
2554 * snd_soc_tplg_component_remove(scomp) will be called
2555 * if snd_soc_tplg_component_load(scomp) failed and all
2556 * objects in the scomp will be removed. No need to call
2557 * snd_soc_tplg_component_remove(scomp) here.
2558 */
2559 dev_err(scomp->dev, "tplg request firmware %s failed err: %d\n",
2560 tplg_files[i], ret);
2561 goto out;
2562 }
2563
2564 if (sdev->dspless_mode_selected)
2565 ret = snd_soc_tplg_component_load(scomp, &sof_dspless_tplg_ops, fw);
2566 else
2567 ret = snd_soc_tplg_component_load(scomp, &sof_tplg_ops, fw);
2568
2569 release_firmware(fw);
2570
2571 if (ret < 0) {
2572 dev_err(scomp->dev, "tplg %s component load failed %d\n",
2573 tplg_files[i], ret);
2574 goto out;
2575 }
2576 }
2577
2578 /* call sof_complete when topologies are loaded successfully */
2579 ret = sof_complete(scomp);
2580
2581 out:
2582 if (ret >= 0 && sdev->led_present)
2583 ret = snd_ctl_led_request();
2584
2585 kfree(tplg_files);
2586
2587 return ret;
2588 }
2589 EXPORT_SYMBOL(snd_sof_load_topology);
2590