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