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 < 0) { /* FIXME: A zero-size array makes no sense */
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 %d\n",
779 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 %d\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 %d name : %s\n",
974 hdr->type, hdr->name);
975
976 scontrol = kzalloc(sizeof(*scontrol), GFP_KERNEL);
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 %d:%d:%d\n",
1019 hdr->ops.get, hdr->ops.put, hdr->ops.info);
1020 kfree(scontrol->name);
1021 kfree(scontrol);
1022 return 0;
1023 }
1024
1025 if (ret < 0) {
1026 kfree(scontrol->name);
1027 kfree(scontrol);
1028 return ret;
1029 }
1030
1031 scontrol->led_ctl.led_value = -1;
1032
1033 dobj->private = scontrol;
1034 list_add(&scontrol->list, &sdev->kcontrol_list);
1035 return 0;
1036 }
1037
sof_control_unload(struct snd_soc_component * scomp,struct snd_soc_dobj * dobj)1038 static int sof_control_unload(struct snd_soc_component *scomp,
1039 struct snd_soc_dobj *dobj)
1040 {
1041 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1042 const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
1043 struct snd_sof_control *scontrol = dobj->private;
1044 int ret = 0;
1045
1046 dev_dbg(scomp->dev, "tplg: unload control name : %s\n", scontrol->name);
1047
1048 if (tplg_ops && tplg_ops->control_free) {
1049 ret = tplg_ops->control_free(sdev, scontrol);
1050 if (ret < 0)
1051 dev_err(scomp->dev, "failed to free control: %s\n", scontrol->name);
1052 }
1053
1054 /* free all data before returning in case of error too */
1055 kfree(scontrol->ipc_control_data);
1056 kfree(scontrol->priv);
1057 kfree(scontrol->name);
1058 list_del(&scontrol->list);
1059 kfree(scontrol);
1060
1061 return ret;
1062 }
1063
1064 /*
1065 * DAI Topology
1066 */
1067
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)1068 static int sof_connect_dai_widget(struct snd_soc_component *scomp,
1069 struct snd_soc_dapm_widget *w,
1070 struct snd_soc_tplg_dapm_widget *tw,
1071 struct snd_sof_dai *dai)
1072 {
1073 struct snd_soc_card *card = scomp->card;
1074 struct snd_soc_pcm_runtime *rtd, *full, *partial;
1075 struct snd_soc_dai *cpu_dai;
1076 int stream;
1077 int i;
1078
1079 if (!w->sname) {
1080 dev_err(scomp->dev, "Widget %s does not have stream\n", w->name);
1081 return -EINVAL;
1082 }
1083
1084 if (w->id == snd_soc_dapm_dai_out)
1085 stream = SNDRV_PCM_STREAM_CAPTURE;
1086 else if (w->id == snd_soc_dapm_dai_in)
1087 stream = SNDRV_PCM_STREAM_PLAYBACK;
1088 else
1089 goto end;
1090
1091 full = NULL;
1092 partial = NULL;
1093 list_for_each_entry(rtd, &card->rtd_list, list) {
1094 /* does stream match DAI link ? */
1095 if (rtd->dai_link->stream_name) {
1096 if (!strcmp(rtd->dai_link->stream_name, w->sname)) {
1097 full = rtd;
1098 break;
1099 } else if (strstr(rtd->dai_link->stream_name, w->sname)) {
1100 partial = rtd;
1101 }
1102 }
1103 }
1104
1105 rtd = full ? full : partial;
1106 if (rtd) {
1107 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
1108 /*
1109 * Please create DAI widget in the right order
1110 * to ensure BE will connect to the right DAI
1111 * widget.
1112 */
1113 if (!snd_soc_dai_get_widget(cpu_dai, stream)) {
1114 snd_soc_dai_set_widget(cpu_dai, stream, w);
1115 break;
1116 }
1117 }
1118 if (i == rtd->dai_link->num_cpus) {
1119 dev_err(scomp->dev, "error: can't find BE for DAI %s\n", w->name);
1120
1121 return -EINVAL;
1122 }
1123
1124 dai->name = rtd->dai_link->name;
1125 dev_dbg(scomp->dev, "tplg: connected widget %s -> DAI link %s\n",
1126 w->name, rtd->dai_link->name);
1127 }
1128 end:
1129 /* check we have a connection */
1130 if (!dai->name) {
1131 dev_err(scomp->dev, "error: can't connect DAI %s stream %s\n",
1132 w->name, w->sname);
1133 return -EINVAL;
1134 }
1135
1136 return 0;
1137 }
1138
sof_disconnect_dai_widget(struct snd_soc_component * scomp,struct snd_soc_dapm_widget * w)1139 static void sof_disconnect_dai_widget(struct snd_soc_component *scomp,
1140 struct snd_soc_dapm_widget *w)
1141 {
1142 struct snd_soc_card *card = scomp->card;
1143 struct snd_soc_pcm_runtime *rtd;
1144 const char *sname = w->sname;
1145 struct snd_soc_dai *cpu_dai;
1146 int i, stream;
1147
1148 if (!sname)
1149 return;
1150
1151 if (w->id == snd_soc_dapm_dai_out)
1152 stream = SNDRV_PCM_STREAM_CAPTURE;
1153 else if (w->id == snd_soc_dapm_dai_in)
1154 stream = SNDRV_PCM_STREAM_PLAYBACK;
1155 else
1156 return;
1157
1158 list_for_each_entry(rtd, &card->rtd_list, list) {
1159 /* does stream match DAI link ? */
1160 if (!rtd->dai_link->stream_name ||
1161 !strstr(rtd->dai_link->stream_name, sname))
1162 continue;
1163
1164 for_each_rtd_cpu_dais(rtd, i, cpu_dai)
1165 if (snd_soc_dai_get_widget(cpu_dai, stream) == w) {
1166 snd_soc_dai_set_widget(cpu_dai, stream, NULL);
1167 break;
1168 }
1169 }
1170 }
1171
1172 /* bind PCM ID to host component ID */
spcm_bind(struct snd_soc_component * scomp,struct snd_sof_pcm * spcm,int dir)1173 static int spcm_bind(struct snd_soc_component *scomp, struct snd_sof_pcm *spcm,
1174 int dir)
1175 {
1176 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1177 struct snd_sof_widget *host_widget;
1178
1179 if (sdev->dspless_mode_selected)
1180 return 0;
1181
1182 host_widget = snd_sof_find_swidget_sname(scomp,
1183 spcm->pcm.caps[dir].name,
1184 dir);
1185 if (!host_widget) {
1186 dev_err(scomp->dev, "can't find host comp to bind pcm\n");
1187 return -EINVAL;
1188 }
1189
1190 spcm->stream[dir].comp_id = host_widget->comp_id;
1191
1192 return 0;
1193 }
1194
sof_get_token_value(u32 token_id,struct snd_sof_tuple * tuples,int num_tuples)1195 static int sof_get_token_value(u32 token_id, struct snd_sof_tuple *tuples, int num_tuples)
1196 {
1197 int i;
1198
1199 if (!tuples)
1200 return -EINVAL;
1201
1202 for (i = 0; i < num_tuples; i++) {
1203 if (tuples[i].token == token_id)
1204 return tuples[i].value.v;
1205 }
1206
1207 return -EINVAL;
1208 }
1209
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)1210 static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_sof_widget *swidget,
1211 struct snd_soc_tplg_dapm_widget *tw,
1212 enum sof_tokens *object_token_list, int count)
1213 {
1214 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1215 const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
1216 struct snd_soc_tplg_private *private = &tw->priv;
1217 const struct sof_token_info *token_list;
1218 int num_tuples = 0;
1219 int ret, i;
1220
1221 token_list = tplg_ops ? tplg_ops->token_list : NULL;
1222 /* nothing to do if token_list is NULL */
1223 if (!token_list)
1224 return 0;
1225
1226 if (count > 0 && !object_token_list) {
1227 dev_err(scomp->dev, "No token list for widget %s\n", swidget->widget->name);
1228 return -EINVAL;
1229 }
1230
1231 /* calculate max size of tuples array */
1232 for (i = 0; i < count; i++)
1233 num_tuples += token_list[object_token_list[i]].count;
1234
1235 /* allocate memory for tuples array */
1236 swidget->tuples = kcalloc(num_tuples, sizeof(*swidget->tuples), GFP_KERNEL);
1237 if (!swidget->tuples)
1238 return -ENOMEM;
1239
1240 /* parse token list for widget */
1241 for (i = 0; i < count; i++) {
1242 int num_sets = 1;
1243
1244 if (object_token_list[i] >= SOF_TOKEN_COUNT) {
1245 dev_err(scomp->dev, "Invalid token id %d for widget %s\n",
1246 object_token_list[i], swidget->widget->name);
1247 ret = -EINVAL;
1248 goto err;
1249 }
1250
1251 switch (object_token_list[i]) {
1252 case SOF_COMP_EXT_TOKENS:
1253 /* parse and save UUID in swidget */
1254 ret = sof_parse_tokens(scomp, swidget,
1255 token_list[object_token_list[i]].tokens,
1256 token_list[object_token_list[i]].count,
1257 private->array, le32_to_cpu(private->size));
1258 if (ret < 0) {
1259 dev_err(scomp->dev, "Failed parsing %s for widget %s\n",
1260 token_list[object_token_list[i]].name,
1261 swidget->widget->name);
1262 goto err;
1263 }
1264
1265 continue;
1266 case SOF_IN_AUDIO_FORMAT_TOKENS:
1267 num_sets = sof_get_token_value(SOF_TKN_COMP_NUM_INPUT_AUDIO_FORMATS,
1268 swidget->tuples, swidget->num_tuples);
1269 if (num_sets < 0) {
1270 dev_err(sdev->dev, "Invalid input audio format count for %s\n",
1271 swidget->widget->name);
1272 ret = num_sets;
1273 goto err;
1274 }
1275 break;
1276 case SOF_OUT_AUDIO_FORMAT_TOKENS:
1277 num_sets = sof_get_token_value(SOF_TKN_COMP_NUM_OUTPUT_AUDIO_FORMATS,
1278 swidget->tuples, swidget->num_tuples);
1279 if (num_sets < 0) {
1280 dev_err(sdev->dev, "Invalid output audio format count for %s\n",
1281 swidget->widget->name);
1282 ret = num_sets;
1283 goto err;
1284 }
1285 break;
1286 default:
1287 break;
1288 }
1289
1290 if (num_sets > 1) {
1291 struct snd_sof_tuple *new_tuples;
1292
1293 num_tuples += token_list[object_token_list[i]].count * (num_sets - 1);
1294 new_tuples = krealloc_array(swidget->tuples,
1295 num_tuples, sizeof(*new_tuples), GFP_KERNEL);
1296 if (!new_tuples) {
1297 ret = -ENOMEM;
1298 goto err;
1299 }
1300
1301 swidget->tuples = new_tuples;
1302 }
1303
1304 /* copy one set of tuples per token ID into swidget->tuples */
1305 ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size),
1306 object_token_list[i], num_sets, swidget->tuples,
1307 num_tuples, &swidget->num_tuples);
1308 if (ret < 0) {
1309 dev_err(scomp->dev, "Failed parsing %s for widget %s err: %d\n",
1310 token_list[object_token_list[i]].name, swidget->widget->name, ret);
1311 goto err;
1312 }
1313 }
1314
1315 return 0;
1316 err:
1317 kfree(swidget->tuples);
1318 return ret;
1319 }
1320
sof_free_pin_binding(struct snd_sof_widget * swidget,bool pin_type)1321 static void sof_free_pin_binding(struct snd_sof_widget *swidget,
1322 bool pin_type)
1323 {
1324 char **pin_binding;
1325 u32 num_pins;
1326 int i;
1327
1328 if (pin_type == SOF_PIN_TYPE_INPUT) {
1329 pin_binding = swidget->input_pin_binding;
1330 num_pins = swidget->num_input_pins;
1331 } else {
1332 pin_binding = swidget->output_pin_binding;
1333 num_pins = swidget->num_output_pins;
1334 }
1335
1336 if (pin_binding) {
1337 for (i = 0; i < num_pins; i++)
1338 kfree(pin_binding[i]);
1339 }
1340
1341 kfree(pin_binding);
1342 }
1343
sof_parse_pin_binding(struct snd_sof_widget * swidget,struct snd_soc_tplg_private * priv,bool pin_type)1344 static int sof_parse_pin_binding(struct snd_sof_widget *swidget,
1345 struct snd_soc_tplg_private *priv, bool pin_type)
1346 {
1347 const struct sof_topology_token *pin_binding_token;
1348 char *pin_binding[SOF_WIDGET_MAX_NUM_PINS];
1349 int token_count;
1350 u32 num_pins;
1351 char **pb;
1352 int ret;
1353 int i;
1354
1355 if (pin_type == SOF_PIN_TYPE_INPUT) {
1356 num_pins = swidget->num_input_pins;
1357 pin_binding_token = comp_input_pin_binding_tokens;
1358 token_count = ARRAY_SIZE(comp_input_pin_binding_tokens);
1359 } else {
1360 num_pins = swidget->num_output_pins;
1361 pin_binding_token = comp_output_pin_binding_tokens;
1362 token_count = ARRAY_SIZE(comp_output_pin_binding_tokens);
1363 }
1364
1365 memset(pin_binding, 0, SOF_WIDGET_MAX_NUM_PINS * sizeof(char *));
1366 ret = sof_parse_token_sets(swidget->scomp, pin_binding, pin_binding_token,
1367 token_count, priv->array, le32_to_cpu(priv->size),
1368 num_pins, sizeof(char *));
1369 if (ret < 0)
1370 goto err;
1371
1372 /* copy pin binding array to swidget only if it is defined in topology */
1373 if (pin_binding[0]) {
1374 pb = kmemdup_array(pin_binding, num_pins, sizeof(char *), GFP_KERNEL);
1375 if (!pb) {
1376 ret = -ENOMEM;
1377 goto err;
1378 }
1379 if (pin_type == SOF_PIN_TYPE_INPUT)
1380 swidget->input_pin_binding = pb;
1381 else
1382 swidget->output_pin_binding = pb;
1383 }
1384
1385 return 0;
1386
1387 err:
1388 for (i = 0; i < num_pins; i++)
1389 kfree(pin_binding[i]);
1390
1391 return ret;
1392 }
1393
get_w_no_wname_in_long_name(void * elem,void * object,u32 offset)1394 static int get_w_no_wname_in_long_name(void *elem, void *object, u32 offset)
1395 {
1396 struct snd_soc_tplg_vendor_value_elem *velem = elem;
1397 struct snd_soc_dapm_widget *w = object;
1398
1399 w->no_wname_in_kcontrol_name = !!le32_to_cpu(velem->value);
1400 return 0;
1401 }
1402
1403 static const struct sof_topology_token dapm_widget_tokens[] = {
1404 {SOF_TKN_COMP_NO_WNAME_IN_KCONTROL_NAME, SND_SOC_TPLG_TUPLE_TYPE_BOOL,
1405 get_w_no_wname_in_long_name, 0}
1406 };
1407
1408 /* 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)1409 static int sof_widget_ready(struct snd_soc_component *scomp, int index,
1410 struct snd_soc_dapm_widget *w,
1411 struct snd_soc_tplg_dapm_widget *tw)
1412 {
1413 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1414 const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
1415 const struct sof_ipc_tplg_widget_ops *widget_ops;
1416 struct snd_soc_tplg_private *priv = &tw->priv;
1417 enum sof_tokens *token_list = NULL;
1418 struct snd_sof_widget *swidget;
1419 struct snd_sof_dai *dai;
1420 int token_list_size = 0;
1421 int ret = 0;
1422
1423 swidget = kzalloc(sizeof(*swidget), GFP_KERNEL);
1424 if (!swidget)
1425 return -ENOMEM;
1426
1427 swidget->scomp = scomp;
1428 swidget->widget = w;
1429 swidget->comp_id = sdev->next_comp_id++;
1430 swidget->id = w->id;
1431 swidget->pipeline_id = index;
1432 swidget->private = NULL;
1433 mutex_init(&swidget->setup_mutex);
1434
1435 ida_init(&swidget->output_queue_ida);
1436 ida_init(&swidget->input_queue_ida);
1437
1438 ret = sof_parse_tokens(scomp, w, dapm_widget_tokens, ARRAY_SIZE(dapm_widget_tokens),
1439 priv->array, le32_to_cpu(priv->size));
1440 if (ret < 0) {
1441 dev_err(scomp->dev, "failed to parse dapm widget tokens for %s\n",
1442 w->name);
1443 goto widget_free;
1444 }
1445
1446 ret = sof_parse_tokens(scomp, swidget, comp_pin_tokens,
1447 ARRAY_SIZE(comp_pin_tokens), priv->array,
1448 le32_to_cpu(priv->size));
1449 if (ret < 0) {
1450 dev_err(scomp->dev, "failed to parse component pin tokens for %s\n",
1451 w->name);
1452 goto widget_free;
1453 }
1454
1455 if (swidget->num_input_pins > SOF_WIDGET_MAX_NUM_PINS ||
1456 swidget->num_output_pins > SOF_WIDGET_MAX_NUM_PINS) {
1457 dev_err(scomp->dev, "invalid pins for %s: [input: %d, output: %d]\n",
1458 swidget->widget->name, swidget->num_input_pins, swidget->num_output_pins);
1459 ret = -EINVAL;
1460 goto widget_free;
1461 }
1462
1463 if (swidget->num_input_pins > 1) {
1464 ret = sof_parse_pin_binding(swidget, priv, SOF_PIN_TYPE_INPUT);
1465 /* on parsing error, pin binding is not allocated, nothing to free. */
1466 if (ret < 0) {
1467 dev_err(scomp->dev, "failed to parse input pin binding for %s\n",
1468 w->name);
1469 goto widget_free;
1470 }
1471 }
1472
1473 if (swidget->num_output_pins > 1) {
1474 ret = sof_parse_pin_binding(swidget, priv, SOF_PIN_TYPE_OUTPUT);
1475 /* on parsing error, pin binding is not allocated, nothing to free. */
1476 if (ret < 0) {
1477 dev_err(scomp->dev, "failed to parse output pin binding for %s\n",
1478 w->name);
1479 goto widget_free;
1480 }
1481 }
1482
1483 dev_dbg(scomp->dev,
1484 "tplg: widget %d (%s) is ready [type: %d, pipe: %d, pins: %d / %d, stream: %s]\n",
1485 swidget->comp_id, w->name, swidget->id, index,
1486 swidget->num_input_pins, swidget->num_output_pins,
1487 strnlen(w->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0 ? w->sname : "none");
1488
1489 widget_ops = tplg_ops ? tplg_ops->widget : NULL;
1490 if (widget_ops) {
1491 token_list = widget_ops[w->id].token_list;
1492 token_list_size = widget_ops[w->id].token_list_size;
1493 }
1494
1495 /* handle any special case widgets */
1496 switch (w->id) {
1497 case snd_soc_dapm_dai_in:
1498 case snd_soc_dapm_dai_out:
1499 dai = kzalloc(sizeof(*dai), GFP_KERNEL);
1500 if (!dai) {
1501 ret = -ENOMEM;
1502 goto widget_free;
1503 }
1504
1505 ret = sof_widget_parse_tokens(scomp, swidget, tw, token_list, token_list_size);
1506 if (!ret)
1507 ret = sof_connect_dai_widget(scomp, w, tw, dai);
1508 if (ret < 0) {
1509 kfree(dai);
1510 break;
1511 }
1512 list_add(&dai->list, &sdev->dai_list);
1513 swidget->private = dai;
1514 break;
1515 case snd_soc_dapm_effect:
1516 /* check we have some tokens - we need at least process type */
1517 if (le32_to_cpu(tw->priv.size) == 0) {
1518 dev_err(scomp->dev, "error: process tokens not found\n");
1519 ret = -EINVAL;
1520 break;
1521 }
1522 ret = sof_widget_parse_tokens(scomp, swidget, tw, token_list, token_list_size);
1523 break;
1524 case snd_soc_dapm_pga:
1525 if (!le32_to_cpu(tw->num_kcontrols)) {
1526 dev_err(scomp->dev, "invalid kcontrol count %d for volume\n",
1527 tw->num_kcontrols);
1528 ret = -EINVAL;
1529 break;
1530 }
1531
1532 fallthrough;
1533 case snd_soc_dapm_mixer:
1534 case snd_soc_dapm_buffer:
1535 case snd_soc_dapm_scheduler:
1536 case snd_soc_dapm_aif_out:
1537 case snd_soc_dapm_aif_in:
1538 case snd_soc_dapm_src:
1539 case snd_soc_dapm_asrc:
1540 case snd_soc_dapm_siggen:
1541 case snd_soc_dapm_mux:
1542 case snd_soc_dapm_demux:
1543 ret = sof_widget_parse_tokens(scomp, swidget, tw, token_list, token_list_size);
1544 break;
1545 case snd_soc_dapm_switch:
1546 case snd_soc_dapm_dai_link:
1547 case snd_soc_dapm_kcontrol:
1548 default:
1549 dev_dbg(scomp->dev, "widget type %d name %s not handled\n", swidget->id, tw->name);
1550 break;
1551 }
1552
1553 /* check token parsing reply */
1554 if (ret < 0) {
1555 dev_err(scomp->dev,
1556 "failed to add widget type %d name : %s stream %s\n",
1557 swidget->id, tw->name, strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0
1558 ? tw->sname : "none");
1559 goto widget_free;
1560 }
1561
1562 if (sof_debug_check_flag(SOF_DBG_DISABLE_MULTICORE)) {
1563 swidget->core = SOF_DSP_PRIMARY_CORE;
1564 } else {
1565 int core = sof_get_token_value(SOF_TKN_COMP_CORE_ID, swidget->tuples,
1566 swidget->num_tuples);
1567
1568 if (core >= 0)
1569 swidget->core = core;
1570 }
1571
1572 /* bind widget to external event */
1573 if (tw->event_type) {
1574 if (widget_ops && widget_ops[w->id].bind_event) {
1575 ret = widget_ops[w->id].bind_event(scomp, swidget,
1576 le16_to_cpu(tw->event_type));
1577 if (ret) {
1578 dev_err(scomp->dev, "widget event binding failed for %s\n",
1579 swidget->widget->name);
1580 goto free;
1581 }
1582 }
1583 }
1584
1585 /* create and add pipeline for scheduler type widgets */
1586 if (w->id == snd_soc_dapm_scheduler) {
1587 struct snd_sof_pipeline *spipe;
1588
1589 spipe = kzalloc(sizeof(*spipe), GFP_KERNEL);
1590 if (!spipe) {
1591 ret = -ENOMEM;
1592 goto free;
1593 }
1594
1595 spipe->pipe_widget = swidget;
1596 swidget->spipe = spipe;
1597 list_add(&spipe->list, &sdev->pipeline_list);
1598 }
1599
1600 w->dobj.private = swidget;
1601 list_add(&swidget->list, &sdev->widget_list);
1602 return ret;
1603 free:
1604 kfree(swidget->private);
1605 kfree(swidget->tuples);
1606 widget_free:
1607 kfree(swidget);
1608 return ret;
1609 }
1610
sof_route_unload(struct snd_soc_component * scomp,struct snd_soc_dobj * dobj)1611 static int sof_route_unload(struct snd_soc_component *scomp,
1612 struct snd_soc_dobj *dobj)
1613 {
1614 struct snd_sof_route *sroute;
1615
1616 sroute = dobj->private;
1617 if (!sroute)
1618 return 0;
1619
1620 /* free sroute and its private data */
1621 kfree(sroute->private);
1622 list_del(&sroute->list);
1623 kfree(sroute);
1624
1625 return 0;
1626 }
1627
sof_widget_unload(struct snd_soc_component * scomp,struct snd_soc_dobj * dobj)1628 static int sof_widget_unload(struct snd_soc_component *scomp,
1629 struct snd_soc_dobj *dobj)
1630 {
1631 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1632 const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
1633 const struct sof_ipc_tplg_widget_ops *widget_ops;
1634 const struct snd_kcontrol_new *kc;
1635 struct snd_soc_dapm_widget *widget;
1636 struct snd_sof_control *scontrol;
1637 struct snd_sof_widget *swidget;
1638 struct soc_mixer_control *sm;
1639 struct soc_bytes_ext *sbe;
1640 struct snd_sof_dai *dai;
1641 struct soc_enum *se;
1642 int i;
1643
1644 swidget = dobj->private;
1645 if (!swidget)
1646 return 0;
1647
1648 widget = swidget->widget;
1649
1650 switch (swidget->id) {
1651 case snd_soc_dapm_dai_in:
1652 case snd_soc_dapm_dai_out:
1653 dai = swidget->private;
1654
1655 if (dai)
1656 list_del(&dai->list);
1657
1658 sof_disconnect_dai_widget(scomp, widget);
1659
1660 break;
1661 case snd_soc_dapm_scheduler:
1662 {
1663 struct snd_sof_pipeline *spipe = swidget->spipe;
1664
1665 list_del(&spipe->list);
1666 kfree(spipe);
1667 swidget->spipe = NULL;
1668 break;
1669 }
1670 default:
1671 break;
1672 }
1673 for (i = 0; i < widget->num_kcontrols; i++) {
1674 kc = &widget->kcontrol_news[i];
1675 switch (widget->dobj.widget.kcontrol_type[i]) {
1676 case SND_SOC_TPLG_TYPE_MIXER:
1677 sm = (struct soc_mixer_control *)kc->private_value;
1678 scontrol = sm->dobj.private;
1679 if (sm->max > 1)
1680 kfree(scontrol->volume_table);
1681 break;
1682 case SND_SOC_TPLG_TYPE_ENUM:
1683 se = (struct soc_enum *)kc->private_value;
1684 scontrol = se->dobj.private;
1685 break;
1686 case SND_SOC_TPLG_TYPE_BYTES:
1687 sbe = (struct soc_bytes_ext *)kc->private_value;
1688 scontrol = sbe->dobj.private;
1689 break;
1690 default:
1691 dev_warn(scomp->dev, "unsupported kcontrol_type\n");
1692 goto out;
1693 }
1694 kfree(scontrol->ipc_control_data);
1695 list_del(&scontrol->list);
1696 kfree(scontrol->name);
1697 kfree(scontrol);
1698 }
1699
1700 out:
1701 /* free IPC related data */
1702 widget_ops = tplg_ops ? tplg_ops->widget : NULL;
1703 if (widget_ops && widget_ops[swidget->id].ipc_free)
1704 widget_ops[swidget->id].ipc_free(swidget);
1705
1706 ida_destroy(&swidget->output_queue_ida);
1707 ida_destroy(&swidget->input_queue_ida);
1708
1709 sof_free_pin_binding(swidget, SOF_PIN_TYPE_INPUT);
1710 sof_free_pin_binding(swidget, SOF_PIN_TYPE_OUTPUT);
1711
1712 kfree(swidget->tuples);
1713
1714 /* remove and free swidget object */
1715 list_del(&swidget->list);
1716 kfree(swidget);
1717
1718 return 0;
1719 }
1720
1721 /*
1722 * DAI HW configuration.
1723 */
1724
1725 /* 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)1726 static int sof_dai_load(struct snd_soc_component *scomp, int index,
1727 struct snd_soc_dai_driver *dai_drv,
1728 struct snd_soc_tplg_pcm *pcm, struct snd_soc_dai *dai)
1729 {
1730 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1731 const struct sof_ipc_pcm_ops *ipc_pcm_ops = sof_ipc_get_ops(sdev, pcm);
1732 struct snd_soc_tplg_stream_caps *caps;
1733 struct snd_soc_tplg_private *private = &pcm->priv;
1734 struct snd_sof_pcm *spcm;
1735 int stream;
1736 int ret;
1737
1738 /* nothing to do for BEs atm */
1739 if (!pcm)
1740 return 0;
1741
1742 spcm = kzalloc(sizeof(*spcm), GFP_KERNEL);
1743 if (!spcm)
1744 return -ENOMEM;
1745
1746 spcm->scomp = scomp;
1747
1748 for_each_pcm_streams(stream) {
1749 spcm->stream[stream].comp_id = COMP_ID_UNASSIGNED;
1750 if (pcm->compress)
1751 snd_sof_compr_init_elapsed_work(&spcm->stream[stream].period_elapsed_work);
1752 else
1753 snd_sof_pcm_init_elapsed_work(&spcm->stream[stream].period_elapsed_work);
1754 }
1755
1756 spcm->pcm = *pcm;
1757 dev_dbg(scomp->dev, "tplg: load pcm %s\n", pcm->dai_name);
1758
1759 /* perform pcm set op */
1760 if (ipc_pcm_ops && ipc_pcm_ops->pcm_setup) {
1761 ret = ipc_pcm_ops->pcm_setup(sdev, spcm);
1762 if (ret < 0) {
1763 kfree(spcm);
1764 return ret;
1765 }
1766 }
1767
1768 dai_drv->dobj.private = spcm;
1769 list_add(&spcm->list, &sdev->pcm_list);
1770
1771 ret = sof_parse_tokens(scomp, spcm, stream_tokens,
1772 ARRAY_SIZE(stream_tokens), private->array,
1773 le32_to_cpu(private->size));
1774 if (ret) {
1775 dev_err(scomp->dev, "error: parse stream tokens failed %d\n",
1776 le32_to_cpu(private->size));
1777 return ret;
1778 }
1779
1780 /* do we need to allocate playback PCM DMA pages */
1781 if (!spcm->pcm.playback)
1782 goto capture;
1783
1784 stream = SNDRV_PCM_STREAM_PLAYBACK;
1785
1786 caps = &spcm->pcm.caps[stream];
1787
1788 /* allocate playback page table buffer */
1789 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev,
1790 PAGE_SIZE, &spcm->stream[stream].page_table);
1791 if (ret < 0) {
1792 dev_err(scomp->dev, "error: can't alloc page table for %s %d\n",
1793 caps->name, ret);
1794
1795 return ret;
1796 }
1797
1798 /* bind pcm to host comp */
1799 ret = spcm_bind(scomp, spcm, stream);
1800 if (ret) {
1801 dev_err(scomp->dev,
1802 "error: can't bind pcm to host\n");
1803 goto free_playback_tables;
1804 }
1805
1806 capture:
1807 stream = SNDRV_PCM_STREAM_CAPTURE;
1808
1809 /* do we need to allocate capture PCM DMA pages */
1810 if (!spcm->pcm.capture)
1811 return ret;
1812
1813 caps = &spcm->pcm.caps[stream];
1814
1815 /* allocate capture page table buffer */
1816 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev,
1817 PAGE_SIZE, &spcm->stream[stream].page_table);
1818 if (ret < 0) {
1819 dev_err(scomp->dev, "error: can't alloc page table for %s %d\n",
1820 caps->name, ret);
1821 goto free_playback_tables;
1822 }
1823
1824 /* bind pcm to host comp */
1825 ret = spcm_bind(scomp, spcm, stream);
1826 if (ret) {
1827 dev_err(scomp->dev,
1828 "error: can't bind pcm to host\n");
1829 snd_dma_free_pages(&spcm->stream[stream].page_table);
1830 goto free_playback_tables;
1831 }
1832
1833 return ret;
1834
1835 free_playback_tables:
1836 if (spcm->pcm.playback)
1837 snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_PLAYBACK].page_table);
1838
1839 return ret;
1840 }
1841
sof_dai_unload(struct snd_soc_component * scomp,struct snd_soc_dobj * dobj)1842 static int sof_dai_unload(struct snd_soc_component *scomp,
1843 struct snd_soc_dobj *dobj)
1844 {
1845 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1846 const struct sof_ipc_pcm_ops *ipc_pcm_ops = sof_ipc_get_ops(sdev, pcm);
1847 struct snd_sof_pcm *spcm = dobj->private;
1848
1849 /* free PCM DMA pages */
1850 if (spcm->pcm.playback)
1851 snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_PLAYBACK].page_table);
1852
1853 if (spcm->pcm.capture)
1854 snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_CAPTURE].page_table);
1855
1856 /* perform pcm free op */
1857 if (ipc_pcm_ops && ipc_pcm_ops->pcm_free)
1858 ipc_pcm_ops->pcm_free(sdev, spcm);
1859
1860 /* remove from list and free spcm */
1861 list_del(&spcm->list);
1862 kfree(spcm);
1863
1864 return 0;
1865 }
1866
1867 static const struct sof_topology_token common_dai_link_tokens[] = {
1868 {SOF_TKN_DAI_TYPE, SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_dai_type,
1869 offsetof(struct snd_sof_dai_link, type)},
1870 };
1871
1872 /* 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)1873 static int sof_link_load(struct snd_soc_component *scomp, int index, struct snd_soc_dai_link *link,
1874 struct snd_soc_tplg_link_config *cfg)
1875 {
1876 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1877 const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
1878 struct snd_soc_tplg_private *private = &cfg->priv;
1879 const struct sof_token_info *token_list;
1880 struct snd_sof_dai_link *slink;
1881 u32 token_id = 0;
1882 int num_tuples = 0;
1883 int ret, num_sets;
1884
1885 if (!link->platforms) {
1886 dev_err(scomp->dev, "error: no platforms\n");
1887 return -EINVAL;
1888 }
1889 link->platforms->name = dev_name(scomp->dev);
1890
1891 if (tplg_ops && tplg_ops->link_setup) {
1892 ret = tplg_ops->link_setup(sdev, link);
1893 if (ret < 0)
1894 return ret;
1895 }
1896
1897 /* Set nonatomic property for FE dai links as their trigger action involves IPC's */
1898 if (!link->no_pcm) {
1899 link->nonatomic = true;
1900 return 0;
1901 }
1902
1903 /* check we have some tokens - we need at least DAI type */
1904 if (le32_to_cpu(private->size) == 0) {
1905 dev_err(scomp->dev, "error: expected tokens for DAI, none found\n");
1906 return -EINVAL;
1907 }
1908
1909 slink = kzalloc(sizeof(*slink), GFP_KERNEL);
1910 if (!slink)
1911 return -ENOMEM;
1912
1913 slink->num_hw_configs = le32_to_cpu(cfg->num_hw_configs);
1914 slink->hw_configs = kmemdup_array(cfg->hw_config,
1915 slink->num_hw_configs, sizeof(*slink->hw_configs),
1916 GFP_KERNEL);
1917 if (!slink->hw_configs) {
1918 kfree(slink);
1919 return -ENOMEM;
1920 }
1921
1922 slink->default_hw_cfg_id = le32_to_cpu(cfg->default_hw_config_id);
1923 slink->link = link;
1924
1925 dev_dbg(scomp->dev, "tplg: %d hw_configs found, default id: %d for dai link %s!\n",
1926 slink->num_hw_configs, slink->default_hw_cfg_id, link->name);
1927
1928 ret = sof_parse_tokens(scomp, slink, common_dai_link_tokens,
1929 ARRAY_SIZE(common_dai_link_tokens),
1930 private->array, le32_to_cpu(private->size));
1931 if (ret < 0) {
1932 dev_err(scomp->dev, "Failed tp parse common DAI link tokens\n");
1933 kfree(slink->hw_configs);
1934 kfree(slink);
1935 return ret;
1936 }
1937
1938 token_list = tplg_ops ? tplg_ops->token_list : NULL;
1939 if (!token_list)
1940 goto out;
1941
1942 /* calculate size of tuples array */
1943 num_tuples += token_list[SOF_DAI_LINK_TOKENS].count;
1944 num_sets = slink->num_hw_configs;
1945 switch (slink->type) {
1946 case SOF_DAI_INTEL_SSP:
1947 token_id = SOF_SSP_TOKENS;
1948 num_tuples += token_list[SOF_SSP_TOKENS].count * slink->num_hw_configs;
1949 break;
1950 case SOF_DAI_INTEL_DMIC:
1951 token_id = SOF_DMIC_TOKENS;
1952 num_tuples += token_list[SOF_DMIC_TOKENS].count;
1953
1954 /* Allocate memory for max PDM controllers */
1955 num_tuples += token_list[SOF_DMIC_PDM_TOKENS].count * SOF_DAI_INTEL_DMIC_NUM_CTRL;
1956 break;
1957 case SOF_DAI_INTEL_HDA:
1958 token_id = SOF_HDA_TOKENS;
1959 num_tuples += token_list[SOF_HDA_TOKENS].count;
1960 break;
1961 case SOF_DAI_INTEL_ALH:
1962 token_id = SOF_ALH_TOKENS;
1963 num_tuples += token_list[SOF_ALH_TOKENS].count;
1964 break;
1965 case SOF_DAI_IMX_SAI:
1966 token_id = SOF_SAI_TOKENS;
1967 num_tuples += token_list[SOF_SAI_TOKENS].count;
1968 break;
1969 case SOF_DAI_IMX_ESAI:
1970 token_id = SOF_ESAI_TOKENS;
1971 num_tuples += token_list[SOF_ESAI_TOKENS].count;
1972 break;
1973 case SOF_DAI_MEDIATEK_AFE:
1974 token_id = SOF_AFE_TOKENS;
1975 num_tuples += token_list[SOF_AFE_TOKENS].count;
1976 break;
1977 case SOF_DAI_AMD_DMIC:
1978 token_id = SOF_ACPDMIC_TOKENS;
1979 num_tuples += token_list[SOF_ACPDMIC_TOKENS].count;
1980 break;
1981 case SOF_DAI_AMD_BT:
1982 case SOF_DAI_AMD_SP:
1983 case SOF_DAI_AMD_HS:
1984 case SOF_DAI_AMD_SP_VIRTUAL:
1985 case SOF_DAI_AMD_HS_VIRTUAL:
1986 token_id = SOF_ACPI2S_TOKENS;
1987 num_tuples += token_list[SOF_ACPI2S_TOKENS].count;
1988 break;
1989 case SOF_DAI_IMX_MICFIL:
1990 token_id = SOF_MICFIL_TOKENS;
1991 num_tuples += token_list[SOF_MICFIL_TOKENS].count;
1992 break;
1993 case SOF_DAI_AMD_SDW:
1994 token_id = SOF_ACP_SDW_TOKENS;
1995 num_tuples += token_list[SOF_ACP_SDW_TOKENS].count;
1996 break;
1997 default:
1998 break;
1999 }
2000
2001 /* allocate memory for tuples array */
2002 slink->tuples = kcalloc(num_tuples, sizeof(*slink->tuples), GFP_KERNEL);
2003 if (!slink->tuples) {
2004 kfree(slink->hw_configs);
2005 kfree(slink);
2006 return -ENOMEM;
2007 }
2008
2009 if (token_list[SOF_DAI_LINK_TOKENS].tokens) {
2010 /* parse one set of DAI link tokens */
2011 ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size),
2012 SOF_DAI_LINK_TOKENS, 1, slink->tuples,
2013 num_tuples, &slink->num_tuples);
2014 if (ret < 0) {
2015 dev_err(scomp->dev, "failed to parse %s for dai link %s\n",
2016 token_list[SOF_DAI_LINK_TOKENS].name, link->name);
2017 goto err;
2018 }
2019 }
2020
2021 /* nothing more to do if there are no DAI type-specific tokens defined */
2022 if (!token_id || !token_list[token_id].tokens)
2023 goto out;
2024
2025 /* parse "num_sets" sets of DAI-specific tokens */
2026 ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size),
2027 token_id, num_sets, slink->tuples, num_tuples, &slink->num_tuples);
2028 if (ret < 0) {
2029 dev_err(scomp->dev, "failed to parse %s for dai link %s\n",
2030 token_list[token_id].name, link->name);
2031 goto err;
2032 }
2033
2034 /* for DMIC, also parse all sets of DMIC PDM tokens based on active PDM count */
2035 if (token_id == SOF_DMIC_TOKENS) {
2036 num_sets = sof_get_token_value(SOF_TKN_INTEL_DMIC_NUM_PDM_ACTIVE,
2037 slink->tuples, slink->num_tuples);
2038
2039 if (num_sets < 0) {
2040 dev_err(sdev->dev, "Invalid active PDM count for %s\n", link->name);
2041 ret = num_sets;
2042 goto err;
2043 }
2044
2045 ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size),
2046 SOF_DMIC_PDM_TOKENS, num_sets, slink->tuples,
2047 num_tuples, &slink->num_tuples);
2048 if (ret < 0) {
2049 dev_err(scomp->dev, "failed to parse %s for dai link %s\n",
2050 token_list[SOF_DMIC_PDM_TOKENS].name, link->name);
2051 goto err;
2052 }
2053 }
2054 out:
2055 link->dobj.private = slink;
2056 list_add(&slink->list, &sdev->dai_link_list);
2057
2058 return 0;
2059
2060 err:
2061 kfree(slink->tuples);
2062 kfree(slink->hw_configs);
2063 kfree(slink);
2064
2065 return ret;
2066 }
2067
sof_link_unload(struct snd_soc_component * scomp,struct snd_soc_dobj * dobj)2068 static int sof_link_unload(struct snd_soc_component *scomp, struct snd_soc_dobj *dobj)
2069 {
2070 struct snd_sof_dai_link *slink = dobj->private;
2071
2072 if (!slink)
2073 return 0;
2074
2075 slink->link->platforms->name = NULL;
2076
2077 kfree(slink->tuples);
2078 list_del(&slink->list);
2079 kfree(slink->hw_configs);
2080 kfree(slink);
2081 dobj->private = NULL;
2082
2083 return 0;
2084 }
2085
2086 /* DAI link - used for any driver specific init */
sof_route_load(struct snd_soc_component * scomp,int index,struct snd_soc_dapm_route * route)2087 static int sof_route_load(struct snd_soc_component *scomp, int index,
2088 struct snd_soc_dapm_route *route)
2089 {
2090 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
2091 struct snd_sof_widget *source_swidget, *sink_swidget;
2092 struct snd_soc_dobj *dobj = &route->dobj;
2093 struct snd_sof_route *sroute;
2094 int ret = 0;
2095
2096 /* allocate memory for sroute and connect */
2097 sroute = kzalloc(sizeof(*sroute), GFP_KERNEL);
2098 if (!sroute)
2099 return -ENOMEM;
2100
2101 sroute->scomp = scomp;
2102 dev_dbg(scomp->dev, "sink %s control %s source %s\n",
2103 route->sink, route->control ? route->control : "none",
2104 route->source);
2105
2106 /* source component */
2107 source_swidget = snd_sof_find_swidget(scomp, (char *)route->source);
2108 if (!source_swidget) {
2109 dev_err(scomp->dev, "error: source %s not found\n",
2110 route->source);
2111 ret = -EINVAL;
2112 goto err;
2113 }
2114
2115 /*
2116 * Virtual widgets of type output/out_drv may be added in topology
2117 * for compatibility. These are not handled by the FW.
2118 * So, don't send routes whose source/sink widget is of such types
2119 * to the DSP.
2120 */
2121 if (source_swidget->id == snd_soc_dapm_out_drv ||
2122 source_swidget->id == snd_soc_dapm_output)
2123 goto err;
2124
2125 /* sink component */
2126 sink_swidget = snd_sof_find_swidget(scomp, (char *)route->sink);
2127 if (!sink_swidget) {
2128 dev_err(scomp->dev, "error: sink %s not found\n",
2129 route->sink);
2130 ret = -EINVAL;
2131 goto err;
2132 }
2133
2134 /*
2135 * Don't send routes whose sink widget is of type
2136 * output or out_drv to the DSP
2137 */
2138 if (sink_swidget->id == snd_soc_dapm_out_drv ||
2139 sink_swidget->id == snd_soc_dapm_output)
2140 goto err;
2141
2142 sroute->route = route;
2143 dobj->private = sroute;
2144 sroute->src_widget = source_swidget;
2145 sroute->sink_widget = sink_swidget;
2146
2147 /* add route to route list */
2148 list_add(&sroute->list, &sdev->route_list);
2149
2150 return 0;
2151 err:
2152 kfree(sroute);
2153 return ret;
2154 }
2155
2156 /**
2157 * sof_set_widget_pipeline - Set pipeline for a component
2158 * @sdev: pointer to struct snd_sof_dev
2159 * @spipe: pointer to struct snd_sof_pipeline
2160 * @swidget: pointer to struct snd_sof_widget that has the same pipeline ID as @pipe_widget
2161 *
2162 * Return: 0 if successful, -EINVAL on error.
2163 * The function checks if @swidget is associated with any volatile controls. If so, setting
2164 * the dynamic_pipeline_widget is disallowed.
2165 */
sof_set_widget_pipeline(struct snd_sof_dev * sdev,struct snd_sof_pipeline * spipe,struct snd_sof_widget * swidget)2166 static int sof_set_widget_pipeline(struct snd_sof_dev *sdev, struct snd_sof_pipeline *spipe,
2167 struct snd_sof_widget *swidget)
2168 {
2169 struct snd_sof_widget *pipe_widget = spipe->pipe_widget;
2170 struct snd_sof_control *scontrol;
2171
2172 if (pipe_widget->dynamic_pipeline_widget) {
2173 /* dynamic widgets cannot have volatile kcontrols */
2174 list_for_each_entry(scontrol, &sdev->kcontrol_list, list)
2175 if (scontrol->comp_id == swidget->comp_id &&
2176 (scontrol->access & SNDRV_CTL_ELEM_ACCESS_VOLATILE)) {
2177 dev_err(sdev->dev,
2178 "error: volatile control found for dynamic widget %s\n",
2179 swidget->widget->name);
2180 return -EINVAL;
2181 }
2182 }
2183
2184 /* set the pipeline and apply the dynamic_pipeline_widget_flag */
2185 swidget->spipe = spipe;
2186 swidget->dynamic_pipeline_widget = pipe_widget->dynamic_pipeline_widget;
2187
2188 return 0;
2189 }
2190
2191 /* completion - called at completion of firmware loading */
sof_complete(struct snd_soc_component * scomp)2192 static int sof_complete(struct snd_soc_component *scomp)
2193 {
2194 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
2195 const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
2196 const struct sof_ipc_tplg_widget_ops *widget_ops;
2197 struct snd_sof_control *scontrol;
2198 struct snd_sof_pipeline *spipe;
2199 int ret;
2200
2201 widget_ops = tplg_ops ? tplg_ops->widget : NULL;
2202
2203 /* first update all control IPC structures based on the IPC version */
2204 if (tplg_ops && tplg_ops->control_setup)
2205 list_for_each_entry(scontrol, &sdev->kcontrol_list, list) {
2206 ret = tplg_ops->control_setup(sdev, scontrol);
2207 if (ret < 0) {
2208 dev_err(sdev->dev, "failed updating IPC struct for control %s\n",
2209 scontrol->name);
2210 return ret;
2211 }
2212 }
2213
2214 /* set up the IPC structures for the pipeline widgets */
2215 list_for_each_entry(spipe, &sdev->pipeline_list, list) {
2216 struct snd_sof_widget *pipe_widget = spipe->pipe_widget;
2217 struct snd_sof_widget *swidget;
2218
2219 pipe_widget->instance_id = -EINVAL;
2220
2221 /* Update the scheduler widget's IPC structure */
2222 if (widget_ops && widget_ops[pipe_widget->id].ipc_setup) {
2223 ret = widget_ops[pipe_widget->id].ipc_setup(pipe_widget);
2224 if (ret < 0) {
2225 dev_err(sdev->dev, "failed updating IPC struct for %s\n",
2226 pipe_widget->widget->name);
2227 return ret;
2228 }
2229 }
2230
2231 /* set the pipeline and update the IPC structure for the non scheduler widgets */
2232 list_for_each_entry(swidget, &sdev->widget_list, list)
2233 if (swidget->widget->id != snd_soc_dapm_scheduler &&
2234 swidget->pipeline_id == pipe_widget->pipeline_id) {
2235 ret = sof_set_widget_pipeline(sdev, spipe, swidget);
2236 if (ret < 0)
2237 return ret;
2238
2239 if (widget_ops && widget_ops[swidget->id].ipc_setup) {
2240 ret = widget_ops[swidget->id].ipc_setup(swidget);
2241 if (ret < 0) {
2242 dev_err(sdev->dev,
2243 "failed updating IPC struct for %s\n",
2244 swidget->widget->name);
2245 return ret;
2246 }
2247 }
2248 }
2249 }
2250
2251 /* verify topology components loading including dynamic pipelines */
2252 if (sof_debug_check_flag(SOF_DBG_VERIFY_TPLG)) {
2253 if (tplg_ops && tplg_ops->set_up_all_pipelines &&
2254 tplg_ops->tear_down_all_pipelines) {
2255 ret = tplg_ops->set_up_all_pipelines(sdev, true);
2256 if (ret < 0) {
2257 dev_err(sdev->dev, "Failed to set up all topology pipelines: %d\n",
2258 ret);
2259 return ret;
2260 }
2261
2262 ret = tplg_ops->tear_down_all_pipelines(sdev, true);
2263 if (ret < 0) {
2264 dev_err(sdev->dev, "Failed to tear down topology pipelines: %d\n",
2265 ret);
2266 return ret;
2267 }
2268 }
2269 }
2270
2271 /* set up static pipelines */
2272 if (tplg_ops && tplg_ops->set_up_all_pipelines)
2273 return tplg_ops->set_up_all_pipelines(sdev, false);
2274
2275 return 0;
2276 }
2277
2278 /* manifest - optional to inform component of manifest */
sof_manifest(struct snd_soc_component * scomp,int index,struct snd_soc_tplg_manifest * man)2279 static int sof_manifest(struct snd_soc_component *scomp, int index,
2280 struct snd_soc_tplg_manifest *man)
2281 {
2282 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
2283 const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
2284
2285 if (tplg_ops && tplg_ops->parse_manifest)
2286 return tplg_ops->parse_manifest(scomp, index, man);
2287
2288 return 0;
2289 }
2290
2291 /* vendor specific kcontrol handlers available for binding */
2292 static const struct snd_soc_tplg_kcontrol_ops sof_io_ops[] = {
2293 {SOF_TPLG_KCTL_VOL_ID, snd_sof_volume_get, snd_sof_volume_put},
2294 {SOF_TPLG_KCTL_BYTES_ID, snd_sof_bytes_get, snd_sof_bytes_put},
2295 {SOF_TPLG_KCTL_ENUM_ID, snd_sof_enum_get, snd_sof_enum_put},
2296 {SOF_TPLG_KCTL_SWITCH_ID, snd_sof_switch_get, snd_sof_switch_put},
2297 };
2298
2299 /* vendor specific bytes ext handlers available for binding */
2300 static const struct snd_soc_tplg_bytes_ext_ops sof_bytes_ext_ops[] = {
2301 {SOF_TPLG_KCTL_BYTES_ID, snd_sof_bytes_ext_get, snd_sof_bytes_ext_put},
2302 {SOF_TPLG_KCTL_BYTES_VOLATILE_RO, snd_sof_bytes_ext_volatile_get},
2303 };
2304
2305 static const struct snd_soc_tplg_ops sof_tplg_ops = {
2306 /* external kcontrol init - used for any driver specific init */
2307 .control_load = sof_control_load,
2308 .control_unload = sof_control_unload,
2309
2310 /* external kcontrol init - used for any driver specific init */
2311 .dapm_route_load = sof_route_load,
2312 .dapm_route_unload = sof_route_unload,
2313
2314 /* external widget init - used for any driver specific init */
2315 /* .widget_load is not currently used */
2316 .widget_ready = sof_widget_ready,
2317 .widget_unload = sof_widget_unload,
2318
2319 /* FE DAI - used for any driver specific init */
2320 .dai_load = sof_dai_load,
2321 .dai_unload = sof_dai_unload,
2322
2323 /* DAI link - used for any driver specific init */
2324 .link_load = sof_link_load,
2325 .link_unload = sof_link_unload,
2326
2327 /*
2328 * No need to set the complete callback. sof_complete will be called explicitly after
2329 * topology loading is complete.
2330 */
2331
2332 /* manifest - optional to inform component of manifest */
2333 .manifest = sof_manifest,
2334
2335 /* vendor specific kcontrol handlers available for binding */
2336 .io_ops = sof_io_ops,
2337 .io_ops_count = ARRAY_SIZE(sof_io_ops),
2338
2339 /* vendor specific bytes ext handlers available for binding */
2340 .bytes_ext_ops = sof_bytes_ext_ops,
2341 .bytes_ext_ops_count = ARRAY_SIZE(sof_bytes_ext_ops),
2342 };
2343
snd_sof_dspless_kcontrol(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2344 static int snd_sof_dspless_kcontrol(struct snd_kcontrol *kcontrol,
2345 struct snd_ctl_elem_value *ucontrol)
2346 {
2347 return 0;
2348 }
2349
2350 static const struct snd_soc_tplg_kcontrol_ops sof_dspless_io_ops[] = {
2351 {SOF_TPLG_KCTL_VOL_ID, snd_sof_dspless_kcontrol, snd_sof_dspless_kcontrol},
2352 {SOF_TPLG_KCTL_BYTES_ID, snd_sof_dspless_kcontrol, snd_sof_dspless_kcontrol},
2353 {SOF_TPLG_KCTL_ENUM_ID, snd_sof_dspless_kcontrol, snd_sof_dspless_kcontrol},
2354 {SOF_TPLG_KCTL_SWITCH_ID, snd_sof_dspless_kcontrol, snd_sof_dspless_kcontrol},
2355 };
2356
snd_sof_dspless_bytes_ext_get(struct snd_kcontrol * kcontrol,unsigned int __user * binary_data,unsigned int size)2357 static int snd_sof_dspless_bytes_ext_get(struct snd_kcontrol *kcontrol,
2358 unsigned int __user *binary_data,
2359 unsigned int size)
2360 {
2361 return 0;
2362 }
2363
snd_sof_dspless_bytes_ext_put(struct snd_kcontrol * kcontrol,const unsigned int __user * binary_data,unsigned int size)2364 static int snd_sof_dspless_bytes_ext_put(struct snd_kcontrol *kcontrol,
2365 const unsigned int __user *binary_data,
2366 unsigned int size)
2367 {
2368 return 0;
2369 }
2370
2371 static const struct snd_soc_tplg_bytes_ext_ops sof_dspless_bytes_ext_ops[] = {
2372 {SOF_TPLG_KCTL_BYTES_ID, snd_sof_dspless_bytes_ext_get, snd_sof_dspless_bytes_ext_put},
2373 {SOF_TPLG_KCTL_BYTES_VOLATILE_RO, snd_sof_dspless_bytes_ext_get},
2374 };
2375
2376 /* 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)2377 static int sof_dspless_widget_ready(struct snd_soc_component *scomp, int index,
2378 struct snd_soc_dapm_widget *w,
2379 struct snd_soc_tplg_dapm_widget *tw)
2380 {
2381 if (WIDGET_IS_DAI(w->id)) {
2382 static const struct sof_topology_token dai_tokens[] = {
2383 {SOF_TKN_DAI_TYPE, SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_dai_type, 0}};
2384 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
2385 struct snd_soc_tplg_private *priv = &tw->priv;
2386 struct snd_sof_widget *swidget;
2387 struct snd_sof_dai *sdai;
2388 int ret;
2389
2390 swidget = kzalloc(sizeof(*swidget), GFP_KERNEL);
2391 if (!swidget)
2392 return -ENOMEM;
2393
2394 sdai = kzalloc(sizeof(*sdai), GFP_KERNEL);
2395 if (!sdai) {
2396 kfree(swidget);
2397 return -ENOMEM;
2398 }
2399
2400 ret = sof_parse_tokens(scomp, &sdai->type, dai_tokens, ARRAY_SIZE(dai_tokens),
2401 priv->array, le32_to_cpu(priv->size));
2402 if (ret < 0) {
2403 dev_err(scomp->dev, "Failed to parse DAI tokens for %s\n", tw->name);
2404 kfree(swidget);
2405 kfree(sdai);
2406 return ret;
2407 }
2408
2409 ret = sof_connect_dai_widget(scomp, w, tw, sdai);
2410 if (ret) {
2411 kfree(swidget);
2412 kfree(sdai);
2413 return ret;
2414 }
2415
2416 swidget->scomp = scomp;
2417 swidget->widget = w;
2418 swidget->private = sdai;
2419 mutex_init(&swidget->setup_mutex);
2420 w->dobj.private = swidget;
2421 list_add(&swidget->list, &sdev->widget_list);
2422 }
2423
2424 return 0;
2425 }
2426
sof_dspless_widget_unload(struct snd_soc_component * scomp,struct snd_soc_dobj * dobj)2427 static int sof_dspless_widget_unload(struct snd_soc_component *scomp,
2428 struct snd_soc_dobj *dobj)
2429 {
2430 struct snd_soc_dapm_widget *w = container_of(dobj, struct snd_soc_dapm_widget, dobj);
2431
2432 if (WIDGET_IS_DAI(w->id)) {
2433 struct snd_sof_widget *swidget = dobj->private;
2434
2435 sof_disconnect_dai_widget(scomp, w);
2436
2437 if (!swidget)
2438 return 0;
2439
2440 /* remove and free swidget object */
2441 list_del(&swidget->list);
2442 kfree(swidget->private);
2443 kfree(swidget);
2444 }
2445
2446 return 0;
2447 }
2448
sof_dspless_link_load(struct snd_soc_component * scomp,int index,struct snd_soc_dai_link * link,struct snd_soc_tplg_link_config * cfg)2449 static int sof_dspless_link_load(struct snd_soc_component *scomp, int index,
2450 struct snd_soc_dai_link *link,
2451 struct snd_soc_tplg_link_config *cfg)
2452 {
2453 link->platforms->name = dev_name(scomp->dev);
2454
2455 /* Set nonatomic property for FE dai links for FE-BE compatibility */
2456 if (!link->no_pcm)
2457 link->nonatomic = true;
2458
2459 return 0;
2460 }
2461
2462 static const struct snd_soc_tplg_ops sof_dspless_tplg_ops = {
2463 /* external widget init - used for any driver specific init */
2464 .widget_ready = sof_dspless_widget_ready,
2465 .widget_unload = sof_dspless_widget_unload,
2466
2467 /* FE DAI - used for any driver specific init */
2468 .dai_load = sof_dai_load,
2469 .dai_unload = sof_dai_unload,
2470
2471 /* DAI link - used for any driver specific init */
2472 .link_load = sof_dspless_link_load,
2473
2474 /* vendor specific kcontrol handlers available for binding */
2475 .io_ops = sof_dspless_io_ops,
2476 .io_ops_count = ARRAY_SIZE(sof_dspless_io_ops),
2477
2478 /* vendor specific bytes ext handlers available for binding */
2479 .bytes_ext_ops = sof_dspless_bytes_ext_ops,
2480 .bytes_ext_ops_count = ARRAY_SIZE(sof_dspless_bytes_ext_ops),
2481 };
2482
snd_sof_load_topology(struct snd_soc_component * scomp,const char * file)2483 int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
2484 {
2485 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
2486 struct snd_sof_pdata *sof_pdata = sdev->pdata;
2487 const char *tplg_filename_prefix = sof_pdata->tplg_filename_prefix;
2488 const struct firmware *fw;
2489 const char **tplg_files;
2490 int tplg_cnt = 0;
2491 int ret;
2492 int i;
2493
2494 tplg_files = kcalloc(scomp->card->num_links, sizeof(char *), GFP_KERNEL);
2495 if (!tplg_files)
2496 return -ENOMEM;
2497
2498 if (!sof_pdata->disable_function_topology && !disable_function_topology &&
2499 sof_pdata->machine && sof_pdata->machine->get_function_tplg_files) {
2500 tplg_cnt = sof_pdata->machine->get_function_tplg_files(scomp->card,
2501 sof_pdata->machine,
2502 tplg_filename_prefix,
2503 &tplg_files);
2504 if (tplg_cnt < 0) {
2505 kfree(tplg_files);
2506 return tplg_cnt;
2507 }
2508 }
2509
2510 /*
2511 * The monolithic topology will be used if there is no get_function_tplg_files
2512 * callback or the callback returns 0.
2513 */
2514 if (!tplg_cnt) {
2515 tplg_files[0] = file;
2516 tplg_cnt = 1;
2517 dev_dbg(scomp->dev, "loading topology: %s\n", file);
2518 } else {
2519 dev_info(scomp->dev, "Using function topologies instead %s\n", file);
2520 }
2521
2522 for (i = 0; i < tplg_cnt; i++) {
2523 /* Only print the file names if the function topologies are used */
2524 if (tplg_files[0] != file)
2525 dev_info(scomp->dev, "loading topology %d: %s\n", i, tplg_files[i]);
2526
2527 ret = request_firmware(&fw, tplg_files[i], scomp->dev);
2528 if (ret < 0) {
2529 /*
2530 * snd_soc_tplg_component_remove(scomp) will be called
2531 * if snd_soc_tplg_component_load(scomp) failed and all
2532 * objects in the scomp will be removed. No need to call
2533 * snd_soc_tplg_component_remove(scomp) here.
2534 */
2535 dev_err(scomp->dev, "tplg request firmware %s failed err: %d\n",
2536 tplg_files[i], ret);
2537 goto out;
2538 }
2539
2540 if (sdev->dspless_mode_selected)
2541 ret = snd_soc_tplg_component_load(scomp, &sof_dspless_tplg_ops, fw);
2542 else
2543 ret = snd_soc_tplg_component_load(scomp, &sof_tplg_ops, fw);
2544
2545 release_firmware(fw);
2546
2547 if (ret < 0) {
2548 dev_err(scomp->dev, "tplg %s component load failed %d\n",
2549 tplg_files[i], ret);
2550 goto out;
2551 }
2552 }
2553
2554 /* call sof_complete when topologies are loaded successfully */
2555 ret = sof_complete(scomp);
2556
2557 out:
2558 if (ret >= 0 && sdev->led_present)
2559 ret = snd_ctl_led_request();
2560
2561 kfree(tplg_files);
2562
2563 return ret;
2564 }
2565 EXPORT_SYMBOL(snd_sof_load_topology);
2566