Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
0002 //
0003 // This file is provided under a dual BSD/GPLv2 license.  When using or
0004 // redistributing this file, you may do so under either license.
0005 //
0006 // Copyright(c) 2018 Intel Corporation. All rights reserved.
0007 //
0008 // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
0009 //
0010 
0011 #include <linux/bits.h>
0012 #include <linux/device.h>
0013 #include <linux/errno.h>
0014 #include <linux/firmware.h>
0015 #include <linux/workqueue.h>
0016 #include <sound/tlv.h>
0017 #include <uapi/sound/sof/tokens.h>
0018 #include "sof-priv.h"
0019 #include "sof-audio.h"
0020 #include "ops.h"
0021 
0022 #define COMP_ID_UNASSIGNED      0xffffffff
0023 /*
0024  * Constants used in the computation of linear volume gain
0025  * from dB gain 20th root of 10 in Q1.16 fixed-point notation
0026  */
0027 #define VOL_TWENTIETH_ROOT_OF_TEN   73533
0028 /* 40th root of 10 in Q1.16 fixed-point notation*/
0029 #define VOL_FORTIETH_ROOT_OF_TEN    69419
0030 
0031 /* 0.5 dB step value in topology TLV */
0032 #define VOL_HALF_DB_STEP    50
0033 
0034 /* TLV data items */
0035 #define TLV_MIN     0
0036 #define TLV_STEP    1
0037 #define TLV_MUTE    2
0038 
0039 /**
0040  * sof_update_ipc_object - Parse multiple sets of tokens within the token array associated with the
0041  *              token ID.
0042  * @scomp: pointer to SOC component
0043  * @object: target IPC struct to save the parsed values
0044  * @token_id: token ID for the token array to be searched
0045  * @tuples: pointer to the tuples array
0046  * @num_tuples: number of tuples in the tuples array
0047  * @object_size: size of the object
0048  * @token_instance_num: number of times the same @token_id needs to be parsed i.e. the function
0049  *          looks for @token_instance_num of each token in the token array associated
0050  *          with the @token_id
0051  */
0052 int sof_update_ipc_object(struct snd_soc_component *scomp, void *object, enum sof_tokens token_id,
0053               struct snd_sof_tuple *tuples, int num_tuples,
0054               size_t object_size, int token_instance_num)
0055 {
0056     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
0057     const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
0058     const struct sof_token_info *token_list = ipc_tplg_ops->token_list;
0059     const struct sof_topology_token *tokens;
0060     int i, j;
0061 
0062     if (token_list[token_id].count < 0) {
0063         dev_err(scomp->dev, "Invalid token count for token ID: %d\n", token_id);
0064         return -EINVAL;
0065     }
0066 
0067     /* No tokens to match */
0068     if (!token_list[token_id].count)
0069         return 0;
0070 
0071     tokens = token_list[token_id].tokens;
0072     if (!tokens) {
0073         dev_err(scomp->dev, "Invalid tokens for token id: %d\n", token_id);
0074         return -EINVAL;
0075     }
0076 
0077     for (i = 0; i < token_list[token_id].count; i++) {
0078         int offset = 0;
0079         int num_tokens_matched = 0;
0080 
0081         for (j = 0; j < num_tuples; j++) {
0082             if (tokens[i].token == tuples[j].token) {
0083                 switch (tokens[i].type) {
0084                 case SND_SOC_TPLG_TUPLE_TYPE_WORD:
0085                 {
0086                     u32 *val = (u32 *)((u8 *)object + tokens[i].offset +
0087                                offset);
0088 
0089                     *val = tuples[j].value.v;
0090                     break;
0091                 }
0092                 case SND_SOC_TPLG_TUPLE_TYPE_SHORT:
0093                 case SND_SOC_TPLG_TUPLE_TYPE_BOOL:
0094                 {
0095                     u16 *val = (u16 *)((u8 *)object + tokens[i].offset +
0096                                 offset);
0097 
0098                     *val = (u16)tuples[j].value.v;
0099                     break;
0100                 }
0101                 case SND_SOC_TPLG_TUPLE_TYPE_STRING:
0102                 {
0103                     if (!tokens[i].get_token) {
0104                         dev_err(scomp->dev,
0105                             "get_token not defined for token %d in %s\n",
0106                             tokens[i].token, token_list[token_id].name);
0107                         return -EINVAL;
0108                     }
0109 
0110                     tokens[i].get_token((void *)tuples[j].value.s, object,
0111                                 tokens[i].offset + offset);
0112                     break;
0113                 }
0114                 default:
0115                     break;
0116                 }
0117 
0118                 num_tokens_matched++;
0119 
0120                 /* found all required sets of current token. Move to the next one */
0121                 if (!(num_tokens_matched % token_instance_num))
0122                     break;
0123 
0124                 /* move to the next object */
0125                 offset += object_size;
0126             }
0127         }
0128     }
0129 
0130     return 0;
0131 }
0132 
0133 static inline int get_tlv_data(const int *p, int tlv[SOF_TLV_ITEMS])
0134 {
0135     /* we only support dB scale TLV type at the moment */
0136     if ((int)p[SNDRV_CTL_TLVO_TYPE] != SNDRV_CTL_TLVT_DB_SCALE)
0137         return -EINVAL;
0138 
0139     /* min value in topology tlv data is multiplied by 100 */
0140     tlv[TLV_MIN] = (int)p[SNDRV_CTL_TLVO_DB_SCALE_MIN] / 100;
0141 
0142     /* volume steps */
0143     tlv[TLV_STEP] = (int)(p[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] &
0144                 TLV_DB_SCALE_MASK);
0145 
0146     /* mute ON/OFF */
0147     if ((p[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] &
0148         TLV_DB_SCALE_MUTE) == 0)
0149         tlv[TLV_MUTE] = 0;
0150     else
0151         tlv[TLV_MUTE] = 1;
0152 
0153     return 0;
0154 }
0155 
0156 /*
0157  * Function to truncate an unsigned 64-bit number
0158  * by x bits and return 32-bit unsigned number. This
0159  * function also takes care of rounding while truncating
0160  */
0161 static inline u32 vol_shift_64(u64 i, u32 x)
0162 {
0163     /* do not truncate more than 32 bits */
0164     if (x > 32)
0165         x = 32;
0166 
0167     if (x == 0)
0168         return (u32)i;
0169 
0170     return (u32)(((i >> (x - 1)) + 1) >> 1);
0171 }
0172 
0173 /*
0174  * Function to compute a ^ exp where,
0175  * a is a fractional number represented by a fixed-point
0176  * integer with a fractional world length of "fwl"
0177  * exp is an integer
0178  * fwl is the fractional word length
0179  * Return value is a fractional number represented by a
0180  * fixed-point integer with a fractional word length of "fwl"
0181  */
0182 static u32 vol_pow32(u32 a, int exp, u32 fwl)
0183 {
0184     int i, iter;
0185     u32 power = 1 << fwl;
0186     u64 numerator;
0187 
0188     /* if exponent is 0, return 1 */
0189     if (exp == 0)
0190         return power;
0191 
0192     /* determine the number of iterations based on the exponent */
0193     if (exp < 0)
0194         iter = exp * -1;
0195     else
0196         iter = exp;
0197 
0198     /* mutiply a "iter" times to compute power */
0199     for (i = 0; i < iter; i++) {
0200         /*
0201          * Product of 2 Qx.fwl fixed-point numbers yields a Q2*x.2*fwl
0202          * Truncate product back to fwl fractional bits with rounding
0203          */
0204         power = vol_shift_64((u64)power * a, fwl);
0205     }
0206 
0207     if (exp > 0) {
0208         /* if exp is positive, return the result */
0209         return power;
0210     }
0211 
0212     /* if exp is negative, return the multiplicative inverse */
0213     numerator = (u64)1 << (fwl << 1);
0214     do_div(numerator, power);
0215 
0216     return (u32)numerator;
0217 }
0218 
0219 /*
0220  * Function to calculate volume gain from TLV data.
0221  * This function can only handle gain steps that are multiples of 0.5 dB
0222  */
0223 u32 vol_compute_gain(u32 value, int *tlv)
0224 {
0225     int dB_gain;
0226     u32 linear_gain;
0227     int f_step;
0228 
0229     /* mute volume */
0230     if (value == 0 && tlv[TLV_MUTE])
0231         return 0;
0232 
0233     /*
0234      * compute dB gain from tlv. tlv_step
0235      * in topology is multiplied by 100
0236      */
0237     dB_gain = tlv[TLV_MIN] + (value * tlv[TLV_STEP]) / 100;
0238 
0239     /*
0240      * compute linear gain represented by fixed-point
0241      * int with VOLUME_FWL fractional bits
0242      */
0243     linear_gain = vol_pow32(VOL_TWENTIETH_ROOT_OF_TEN, dB_gain, VOLUME_FWL);
0244 
0245     /* extract the fractional part of volume step */
0246     f_step = tlv[TLV_STEP] - (tlv[TLV_STEP] / 100);
0247 
0248     /* if volume step is an odd multiple of 0.5 dB */
0249     if (f_step == VOL_HALF_DB_STEP && (value & 1))
0250         linear_gain = vol_shift_64((u64)linear_gain *
0251                           VOL_FORTIETH_ROOT_OF_TEN,
0252                           VOLUME_FWL);
0253 
0254     return linear_gain;
0255 }
0256 
0257 /*
0258  * Set up volume table for kcontrols from tlv data
0259  * "size" specifies the number of entries in the table
0260  */
0261 static int set_up_volume_table(struct snd_sof_control *scontrol,
0262                    int tlv[SOF_TLV_ITEMS], int size)
0263 {
0264     struct snd_soc_component *scomp = scontrol->scomp;
0265     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
0266     const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
0267 
0268     if (tplg_ops->control->set_up_volume_table)
0269         return tplg_ops->control->set_up_volume_table(scontrol, tlv, size);
0270 
0271     dev_err(scomp->dev, "Mandatory op %s not set\n", __func__);
0272     return -EINVAL;
0273 }
0274 
0275 struct sof_dai_types {
0276     const char *name;
0277     enum sof_ipc_dai_type type;
0278 };
0279 
0280 static const struct sof_dai_types sof_dais[] = {
0281     {"SSP", SOF_DAI_INTEL_SSP},
0282     {"HDA", SOF_DAI_INTEL_HDA},
0283     {"DMIC", SOF_DAI_INTEL_DMIC},
0284     {"ALH", SOF_DAI_INTEL_ALH},
0285     {"SAI", SOF_DAI_IMX_SAI},
0286     {"ESAI", SOF_DAI_IMX_ESAI},
0287     {"ACP", SOF_DAI_AMD_BT},
0288     {"ACPSP", SOF_DAI_AMD_SP},
0289     {"ACPDMIC", SOF_DAI_AMD_DMIC},
0290     {"AFE", SOF_DAI_MEDIATEK_AFE},
0291 };
0292 
0293 static enum sof_ipc_dai_type find_dai(const char *name)
0294 {
0295     int i;
0296 
0297     for (i = 0; i < ARRAY_SIZE(sof_dais); i++) {
0298         if (strcmp(name, sof_dais[i].name) == 0)
0299             return sof_dais[i].type;
0300     }
0301 
0302     return SOF_DAI_INTEL_NONE;
0303 }
0304 
0305 /*
0306  * Supported Frame format types and lookup, add new ones to end of list.
0307  */
0308 
0309 struct sof_frame_types {
0310     const char *name;
0311     enum sof_ipc_frame frame;
0312 };
0313 
0314 static const struct sof_frame_types sof_frames[] = {
0315     {"s16le", SOF_IPC_FRAME_S16_LE},
0316     {"s24le", SOF_IPC_FRAME_S24_4LE},
0317     {"s32le", SOF_IPC_FRAME_S32_LE},
0318     {"float", SOF_IPC_FRAME_FLOAT},
0319 };
0320 
0321 static enum sof_ipc_frame find_format(const char *name)
0322 {
0323     int i;
0324 
0325     for (i = 0; i < ARRAY_SIZE(sof_frames); i++) {
0326         if (strcmp(name, sof_frames[i].name) == 0)
0327             return sof_frames[i].frame;
0328     }
0329 
0330     /* use s32le if nothing is specified */
0331     return SOF_IPC_FRAME_S32_LE;
0332 }
0333 
0334 int get_token_u32(void *elem, void *object, u32 offset)
0335 {
0336     struct snd_soc_tplg_vendor_value_elem *velem = elem;
0337     u32 *val = (u32 *)((u8 *)object + offset);
0338 
0339     *val = le32_to_cpu(velem->value);
0340     return 0;
0341 }
0342 
0343 int get_token_u16(void *elem, void *object, u32 offset)
0344 {
0345     struct snd_soc_tplg_vendor_value_elem *velem = elem;
0346     u16 *val = (u16 *)((u8 *)object + offset);
0347 
0348     *val = (u16)le32_to_cpu(velem->value);
0349     return 0;
0350 }
0351 
0352 int get_token_uuid(void *elem, void *object, u32 offset)
0353 {
0354     struct snd_soc_tplg_vendor_uuid_elem *velem = elem;
0355     u8 *dst = (u8 *)object + offset;
0356 
0357     memcpy(dst, velem->uuid, UUID_SIZE);
0358 
0359     return 0;
0360 }
0361 
0362 int get_token_comp_format(void *elem, void *object, u32 offset)
0363 {
0364     u32 *val = (u32 *)((u8 *)object + offset);
0365 
0366     *val = find_format((const char *)elem);
0367     return 0;
0368 }
0369 
0370 int get_token_dai_type(void *elem, void *object, u32 offset)
0371 {
0372     u32 *val = (u32 *)((u8 *)object + offset);
0373 
0374     *val = find_dai((const char *)elem);
0375     return 0;
0376 }
0377 
0378 /* PCM */
0379 static const struct sof_topology_token stream_tokens[] = {
0380     {SOF_TKN_STREAM_PLAYBACK_COMPATIBLE_D0I3, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16,
0381         offsetof(struct snd_sof_pcm, stream[0].d0i3_compatible)},
0382     {SOF_TKN_STREAM_CAPTURE_COMPATIBLE_D0I3, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16,
0383         offsetof(struct snd_sof_pcm, stream[1].d0i3_compatible)},
0384 };
0385 
0386 /* Leds */
0387 static const struct sof_topology_token led_tokens[] = {
0388     {SOF_TKN_MUTE_LED_USE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
0389         offsetof(struct snd_sof_led_control, use_led)},
0390     {SOF_TKN_MUTE_LED_DIRECTION, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
0391         offsetof(struct snd_sof_led_control, direction)},
0392 };
0393 
0394 /**
0395  * sof_parse_uuid_tokens - Parse multiple sets of UUID tokens
0396  * @scomp: pointer to soc component
0397  * @object: target ipc struct for parsed values
0398  * @offset: offset within the object pointer
0399  * @tokens: array of struct sof_topology_token containing the tokens to be matched
0400  * @num_tokens: number of tokens in tokens array
0401  * @array: source pointer to consecutive vendor arrays in topology
0402  *
0403  * This function parses multiple sets of string type tokens in vendor arrays
0404  */
0405 static int sof_parse_uuid_tokens(struct snd_soc_component *scomp,
0406                   void *object, size_t offset,
0407                   const struct sof_topology_token *tokens, int num_tokens,
0408                   struct snd_soc_tplg_vendor_array *array)
0409 {
0410     struct snd_soc_tplg_vendor_uuid_elem *elem;
0411     int found = 0;
0412     int i, j;
0413 
0414     /* parse element by element */
0415     for (i = 0; i < le32_to_cpu(array->num_elems); i++) {
0416         elem = &array->uuid[i];
0417 
0418         /* search for token */
0419         for (j = 0; j < num_tokens; j++) {
0420             /* match token type */
0421             if (tokens[j].type != SND_SOC_TPLG_TUPLE_TYPE_UUID)
0422                 continue;
0423 
0424             /* match token id */
0425             if (tokens[j].token != le32_to_cpu(elem->token))
0426                 continue;
0427 
0428             /* matched - now load token */
0429             tokens[j].get_token(elem, object,
0430                         offset + tokens[j].offset);
0431 
0432             found++;
0433         }
0434     }
0435 
0436     return found;
0437 }
0438 
0439 /**
0440  * sof_copy_tuples - Parse tokens and copy them to the @tuples array
0441  * @sdev: pointer to struct snd_sof_dev
0442  * @array: source pointer to consecutive vendor arrays in topology
0443  * @array_size: size of @array
0444  * @token_id: Token ID associated with a token array
0445  * @token_instance_num: number of times the same @token_id needs to be parsed i.e. the function
0446  *          looks for @token_instance_num of each token in the token array associated
0447  *          with the @token_id
0448  * @tuples: tuples array to copy the matched tuples to
0449  * @tuples_size: size of @tuples
0450  * @num_copied_tuples: pointer to the number of copied tuples in the tuples array
0451  *
0452  */
0453 static int sof_copy_tuples(struct snd_sof_dev *sdev, struct snd_soc_tplg_vendor_array *array,
0454                int array_size, u32 token_id, int token_instance_num,
0455                struct snd_sof_tuple *tuples, int tuples_size, int *num_copied_tuples)
0456 {
0457     const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
0458     const struct sof_token_info *token_list = ipc_tplg_ops->token_list;
0459     const struct sof_topology_token *tokens;
0460     int found = 0;
0461     int num_tokens, asize;
0462     int i, j;
0463 
0464     /* nothing to do if token_list is NULL */
0465     if (!token_list)
0466         return 0;
0467 
0468     if (!tuples || !num_copied_tuples) {
0469         dev_err(sdev->dev, "Invalid tuples array\n");
0470         return -EINVAL;
0471     }
0472 
0473     tokens = token_list[token_id].tokens;
0474     num_tokens = token_list[token_id].count;
0475 
0476     if (!tokens) {
0477         dev_err(sdev->dev, "No token array defined for token ID: %d\n", token_id);
0478         return -EINVAL;
0479     }
0480 
0481     /* check if there's space in the tuples array for new tokens */
0482     if (*num_copied_tuples >= tuples_size) {
0483         dev_err(sdev->dev, "No space in tuples array for new tokens from %s",
0484             token_list[token_id].name);
0485         return -EINVAL;
0486     }
0487 
0488     while (array_size > 0 && found < num_tokens * token_instance_num) {
0489         asize = le32_to_cpu(array->size);
0490 
0491         /* validate asize */
0492         if (asize < 0) {
0493             dev_err(sdev->dev, "Invalid array size 0x%x\n", asize);
0494             return -EINVAL;
0495         }
0496 
0497         /* make sure there is enough data before parsing */
0498         array_size -= asize;
0499         if (array_size < 0) {
0500             dev_err(sdev->dev, "Invalid array size 0x%x\n", asize);
0501             return -EINVAL;
0502         }
0503 
0504         /* parse element by element */
0505         for (i = 0; i < le32_to_cpu(array->num_elems); i++) {
0506             /* search for token */
0507             for (j = 0; j < num_tokens; j++) {
0508                 /* match token type */
0509                 if (!(tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_WORD ||
0510                       tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_SHORT ||
0511                       tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_BYTE ||
0512                       tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_BOOL ||
0513                       tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_STRING))
0514                     continue;
0515 
0516                 if (tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_STRING) {
0517                     struct snd_soc_tplg_vendor_string_elem *elem;
0518 
0519                     elem = &array->string[i];
0520 
0521                     /* match token id */
0522                     if (tokens[j].token != le32_to_cpu(elem->token))
0523                         continue;
0524 
0525                     tuples[*num_copied_tuples].token = tokens[j].token;
0526                     tuples[*num_copied_tuples].value.s = elem->string;
0527                 } else {
0528                     struct snd_soc_tplg_vendor_value_elem *elem;
0529 
0530                     elem = &array->value[i];
0531 
0532                     /* match token id */
0533                     if (tokens[j].token != le32_to_cpu(elem->token))
0534                         continue;
0535 
0536                     tuples[*num_copied_tuples].token = tokens[j].token;
0537                     tuples[*num_copied_tuples].value.v =
0538                         le32_to_cpu(elem->value);
0539                 }
0540                 found++;
0541                 (*num_copied_tuples)++;
0542 
0543                 /* stop if there's no space for any more new tuples */
0544                 if (*num_copied_tuples == tuples_size)
0545                     return 0;
0546             }
0547         }
0548 
0549         /* next array */
0550         array = (struct snd_soc_tplg_vendor_array *)((u8 *)array + asize);
0551     }
0552 
0553     return 0;
0554 }
0555 
0556 /**
0557  * sof_parse_string_tokens - Parse multiple sets of tokens
0558  * @scomp: pointer to soc component
0559  * @object: target ipc struct for parsed values
0560  * @offset: offset within the object pointer
0561  * @tokens: array of struct sof_topology_token containing the tokens to be matched
0562  * @num_tokens: number of tokens in tokens array
0563  * @array: source pointer to consecutive vendor arrays in topology
0564  *
0565  * This function parses multiple sets of string type tokens in vendor arrays
0566  */
0567 static int sof_parse_string_tokens(struct snd_soc_component *scomp,
0568                    void *object, int offset,
0569                    const struct sof_topology_token *tokens, int num_tokens,
0570                    struct snd_soc_tplg_vendor_array *array)
0571 {
0572     struct snd_soc_tplg_vendor_string_elem *elem;
0573     int found = 0;
0574     int i, j;
0575 
0576     /* parse element by element */
0577     for (i = 0; i < le32_to_cpu(array->num_elems); i++) {
0578         elem = &array->string[i];
0579 
0580         /* search for token */
0581         for (j = 0; j < num_tokens; j++) {
0582             /* match token type */
0583             if (tokens[j].type != SND_SOC_TPLG_TUPLE_TYPE_STRING)
0584                 continue;
0585 
0586             /* match token id */
0587             if (tokens[j].token != le32_to_cpu(elem->token))
0588                 continue;
0589 
0590             /* matched - now load token */
0591             tokens[j].get_token(elem->string, object, offset + tokens[j].offset);
0592 
0593             found++;
0594         }
0595     }
0596 
0597     return found;
0598 }
0599 
0600 /**
0601  * sof_parse_word_tokens - Parse multiple sets of tokens
0602  * @scomp: pointer to soc component
0603  * @object: target ipc struct for parsed values
0604  * @offset: offset within the object pointer
0605  * @tokens: array of struct sof_topology_token containing the tokens to be matched
0606  * @num_tokens: number of tokens in tokens array
0607  * @array: source pointer to consecutive vendor arrays in topology
0608  *
0609  * This function parses multiple sets of word type tokens in vendor arrays
0610  */
0611 static int sof_parse_word_tokens(struct snd_soc_component *scomp,
0612                   void *object, int offset,
0613                   const struct sof_topology_token *tokens, int num_tokens,
0614                   struct snd_soc_tplg_vendor_array *array)
0615 {
0616     struct snd_soc_tplg_vendor_value_elem *elem;
0617     int found = 0;
0618     int i, j;
0619 
0620     /* parse element by element */
0621     for (i = 0; i < le32_to_cpu(array->num_elems); i++) {
0622         elem = &array->value[i];
0623 
0624         /* search for token */
0625         for (j = 0; j < num_tokens; j++) {
0626             /* match token type */
0627             if (!(tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_WORD ||
0628                   tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_SHORT ||
0629                   tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_BYTE ||
0630                   tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_BOOL))
0631                 continue;
0632 
0633             /* match token id */
0634             if (tokens[j].token != le32_to_cpu(elem->token))
0635                 continue;
0636 
0637             /* load token */
0638             tokens[j].get_token(elem, object, offset + tokens[j].offset);
0639 
0640             found++;
0641         }
0642     }
0643 
0644     return found;
0645 }
0646 
0647 /**
0648  * sof_parse_token_sets - Parse multiple sets of tokens
0649  * @scomp: pointer to soc component
0650  * @object: target ipc struct for parsed values
0651  * @tokens: token definition array describing what tokens to parse
0652  * @count: number of tokens in definition array
0653  * @array: source pointer to consecutive vendor arrays in topology
0654  * @array_size: total size of @array
0655  * @token_instance_num: number of times the same tokens needs to be parsed i.e. the function
0656  *          looks for @token_instance_num of each token in the @tokens
0657  * @object_size: offset to next target ipc struct with multiple sets
0658  *
0659  * This function parses multiple sets of tokens in vendor arrays into
0660  * consecutive ipc structs.
0661  */
0662 static int sof_parse_token_sets(struct snd_soc_component *scomp,
0663                 void *object, const struct sof_topology_token *tokens,
0664                 int count, struct snd_soc_tplg_vendor_array *array,
0665                 int array_size, int token_instance_num, size_t object_size)
0666 {
0667     size_t offset = 0;
0668     int found = 0;
0669     int total = 0;
0670     int asize;
0671 
0672     while (array_size > 0 && total < count * token_instance_num) {
0673         asize = le32_to_cpu(array->size);
0674 
0675         /* validate asize */
0676         if (asize < 0) { /* FIXME: A zero-size array makes no sense */
0677             dev_err(scomp->dev, "error: invalid array size 0x%x\n",
0678                 asize);
0679             return -EINVAL;
0680         }
0681 
0682         /* make sure there is enough data before parsing */
0683         array_size -= asize;
0684         if (array_size < 0) {
0685             dev_err(scomp->dev, "error: invalid array size 0x%x\n",
0686                 asize);
0687             return -EINVAL;
0688         }
0689 
0690         /* call correct parser depending on type */
0691         switch (le32_to_cpu(array->type)) {
0692         case SND_SOC_TPLG_TUPLE_TYPE_UUID:
0693             found += sof_parse_uuid_tokens(scomp, object, offset, tokens, count,
0694                                array);
0695             break;
0696         case SND_SOC_TPLG_TUPLE_TYPE_STRING:
0697             found += sof_parse_string_tokens(scomp, object, offset, tokens, count,
0698                              array);
0699             break;
0700         case SND_SOC_TPLG_TUPLE_TYPE_BOOL:
0701         case SND_SOC_TPLG_TUPLE_TYPE_BYTE:
0702         case SND_SOC_TPLG_TUPLE_TYPE_WORD:
0703         case SND_SOC_TPLG_TUPLE_TYPE_SHORT:
0704             found += sof_parse_word_tokens(scomp, object, offset, tokens, count,
0705                                array);
0706             break;
0707         default:
0708             dev_err(scomp->dev, "error: unknown token type %d\n",
0709                 array->type);
0710             return -EINVAL;
0711         }
0712 
0713         /* next array */
0714         array = (struct snd_soc_tplg_vendor_array *)((u8 *)array
0715             + asize);
0716 
0717         /* move to next target struct */
0718         if (found >= count) {
0719             offset += object_size;
0720             total += found;
0721             found = 0;
0722         }
0723     }
0724 
0725     return 0;
0726 }
0727 
0728 /**
0729  * sof_parse_tokens - Parse one set of tokens
0730  * @scomp: pointer to soc component
0731  * @object: target ipc struct for parsed values
0732  * @tokens: token definition array describing what tokens to parse
0733  * @num_tokens: number of tokens in definition array
0734  * @array: source pointer to consecutive vendor arrays in topology
0735  * @array_size: total size of @array
0736  *
0737  * This function parses a single set of tokens in vendor arrays into
0738  * consecutive ipc structs.
0739  */
0740 static int sof_parse_tokens(struct snd_soc_component *scomp,  void *object,
0741                 const struct sof_topology_token *tokens, int num_tokens,
0742                 struct snd_soc_tplg_vendor_array *array,
0743                 int array_size)
0744 
0745 {
0746     /*
0747      * sof_parse_tokens is used when topology contains only a single set of
0748      * identical tuples arrays. So additional parameters to
0749      * sof_parse_token_sets are sets = 1 (only 1 set) and
0750      * object_size = 0 (irrelevant).
0751      */
0752     return sof_parse_token_sets(scomp, object, tokens, num_tokens, array,
0753                     array_size, 1, 0);
0754 }
0755 
0756 /*
0757  * Standard Kcontrols.
0758  */
0759 
0760 static int sof_control_load_volume(struct snd_soc_component *scomp,
0761                    struct snd_sof_control *scontrol,
0762                    struct snd_kcontrol_new *kc,
0763                    struct snd_soc_tplg_ctl_hdr *hdr)
0764 {
0765     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
0766     struct snd_soc_tplg_mixer_control *mc =
0767         container_of(hdr, struct snd_soc_tplg_mixer_control, hdr);
0768     int tlv[SOF_TLV_ITEMS];
0769     unsigned int mask;
0770     int ret;
0771 
0772     /* validate topology data */
0773     if (le32_to_cpu(mc->num_channels) > SND_SOC_TPLG_MAX_CHAN)
0774         return -EINVAL;
0775 
0776     /*
0777      * If control has more than 2 channels we need to override the info. This is because even if
0778      * ASoC layer has defined topology's max channel count to SND_SOC_TPLG_MAX_CHAN = 8, the
0779      * pre-defined dapm control types (and related functions) creating the actual control
0780      * restrict the channels only to mono or stereo.
0781      */
0782     if (le32_to_cpu(mc->num_channels) > 2)
0783         kc->info = snd_sof_volume_info;
0784 
0785     scontrol->comp_id = sdev->next_comp_id;
0786     scontrol->min_volume_step = le32_to_cpu(mc->min);
0787     scontrol->max_volume_step = le32_to_cpu(mc->max);
0788     scontrol->num_channels = le32_to_cpu(mc->num_channels);
0789 
0790     scontrol->max = le32_to_cpu(mc->max);
0791     if (le32_to_cpu(mc->max) == 1)
0792         goto skip;
0793 
0794     /* extract tlv data */
0795     if (!kc->tlv.p || get_tlv_data(kc->tlv.p, tlv) < 0) {
0796         dev_err(scomp->dev, "error: invalid TLV data\n");
0797         return -EINVAL;
0798     }
0799 
0800     /* set up volume table */
0801     ret = set_up_volume_table(scontrol, tlv, le32_to_cpu(mc->max) + 1);
0802     if (ret < 0) {
0803         dev_err(scomp->dev, "error: setting up volume table\n");
0804         return ret;
0805     }
0806 
0807 skip:
0808     /* set up possible led control from mixer private data */
0809     ret = sof_parse_tokens(scomp, &scontrol->led_ctl, led_tokens,
0810                    ARRAY_SIZE(led_tokens), mc->priv.array,
0811                    le32_to_cpu(mc->priv.size));
0812     if (ret != 0) {
0813         dev_err(scomp->dev, "error: parse led tokens failed %d\n",
0814             le32_to_cpu(mc->priv.size));
0815         goto err;
0816     }
0817 
0818     if (scontrol->led_ctl.use_led) {
0819         mask = scontrol->led_ctl.direction ? SNDRV_CTL_ELEM_ACCESS_MIC_LED :
0820                             SNDRV_CTL_ELEM_ACCESS_SPK_LED;
0821         scontrol->access &= ~SNDRV_CTL_ELEM_ACCESS_LED_MASK;
0822         scontrol->access |= mask;
0823         kc->access &= ~SNDRV_CTL_ELEM_ACCESS_LED_MASK;
0824         kc->access |= mask;
0825         sdev->led_present = true;
0826     }
0827 
0828     dev_dbg(scomp->dev, "tplg: load kcontrol index %d chans %d\n",
0829         scontrol->comp_id, scontrol->num_channels);
0830 
0831     return 0;
0832 
0833 err:
0834     if (le32_to_cpu(mc->max) > 1)
0835         kfree(scontrol->volume_table);
0836 
0837     return ret;
0838 }
0839 
0840 static int sof_control_load_enum(struct snd_soc_component *scomp,
0841                  struct snd_sof_control *scontrol,
0842                  struct snd_kcontrol_new *kc,
0843                  struct snd_soc_tplg_ctl_hdr *hdr)
0844 {
0845     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
0846     struct snd_soc_tplg_enum_control *ec =
0847         container_of(hdr, struct snd_soc_tplg_enum_control, hdr);
0848 
0849     /* validate topology data */
0850     if (le32_to_cpu(ec->num_channels) > SND_SOC_TPLG_MAX_CHAN)
0851         return -EINVAL;
0852 
0853     scontrol->comp_id = sdev->next_comp_id;
0854     scontrol->num_channels = le32_to_cpu(ec->num_channels);
0855 
0856     dev_dbg(scomp->dev, "tplg: load kcontrol index %d chans %d comp_id %d\n",
0857         scontrol->comp_id, scontrol->num_channels, scontrol->comp_id);
0858 
0859     return 0;
0860 }
0861 
0862 static int sof_control_load_bytes(struct snd_soc_component *scomp,
0863                   struct snd_sof_control *scontrol,
0864                   struct snd_kcontrol_new *kc,
0865                   struct snd_soc_tplg_ctl_hdr *hdr)
0866 {
0867     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
0868     struct snd_soc_tplg_bytes_control *control =
0869         container_of(hdr, struct snd_soc_tplg_bytes_control, hdr);
0870     struct soc_bytes_ext *sbe = (struct soc_bytes_ext *)kc->private_value;
0871     size_t priv_size = le32_to_cpu(control->priv.size);
0872 
0873     scontrol->max_size = sbe->max;
0874     scontrol->comp_id = sdev->next_comp_id;
0875 
0876     dev_dbg(scomp->dev, "tplg: load kcontrol index %d\n", scontrol->comp_id);
0877 
0878     /* copy the private data */
0879     if (priv_size > 0) {
0880         scontrol->priv = kmemdup(control->priv.data, priv_size, GFP_KERNEL);
0881         if (!scontrol->priv)
0882             return -ENOMEM;
0883 
0884         scontrol->priv_size = priv_size;
0885     }
0886 
0887     return 0;
0888 }
0889 
0890 /* external kcontrol init - used for any driver specific init */
0891 static int sof_control_load(struct snd_soc_component *scomp, int index,
0892                 struct snd_kcontrol_new *kc,
0893                 struct snd_soc_tplg_ctl_hdr *hdr)
0894 {
0895     struct soc_mixer_control *sm;
0896     struct soc_bytes_ext *sbe;
0897     struct soc_enum *se;
0898     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
0899     struct snd_soc_dobj *dobj;
0900     struct snd_sof_control *scontrol;
0901     int ret;
0902 
0903     dev_dbg(scomp->dev, "tplg: load control type %d name : %s\n",
0904         hdr->type, hdr->name);
0905 
0906     scontrol = kzalloc(sizeof(*scontrol), GFP_KERNEL);
0907     if (!scontrol)
0908         return -ENOMEM;
0909 
0910     scontrol->name = kstrdup(hdr->name, GFP_KERNEL);
0911     if (!scontrol->name) {
0912         kfree(scontrol);
0913         return -ENOMEM;
0914     }
0915 
0916     scontrol->scomp = scomp;
0917     scontrol->access = kc->access;
0918     scontrol->info_type = le32_to_cpu(hdr->ops.info);
0919     scontrol->index = kc->index;
0920 
0921     switch (le32_to_cpu(hdr->ops.info)) {
0922     case SND_SOC_TPLG_CTL_VOLSW:
0923     case SND_SOC_TPLG_CTL_VOLSW_SX:
0924     case SND_SOC_TPLG_CTL_VOLSW_XR_SX:
0925         sm = (struct soc_mixer_control *)kc->private_value;
0926         dobj = &sm->dobj;
0927         ret = sof_control_load_volume(scomp, scontrol, kc, hdr);
0928         break;
0929     case SND_SOC_TPLG_CTL_BYTES:
0930         sbe = (struct soc_bytes_ext *)kc->private_value;
0931         dobj = &sbe->dobj;
0932         ret = sof_control_load_bytes(scomp, scontrol, kc, hdr);
0933         break;
0934     case SND_SOC_TPLG_CTL_ENUM:
0935     case SND_SOC_TPLG_CTL_ENUM_VALUE:
0936         se = (struct soc_enum *)kc->private_value;
0937         dobj = &se->dobj;
0938         ret = sof_control_load_enum(scomp, scontrol, kc, hdr);
0939         break;
0940     case SND_SOC_TPLG_CTL_RANGE:
0941     case SND_SOC_TPLG_CTL_STROBE:
0942     case SND_SOC_TPLG_DAPM_CTL_VOLSW:
0943     case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE:
0944     case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT:
0945     case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE:
0946     case SND_SOC_TPLG_DAPM_CTL_PIN:
0947     default:
0948         dev_warn(scomp->dev, "control type not supported %d:%d:%d\n",
0949              hdr->ops.get, hdr->ops.put, hdr->ops.info);
0950         kfree(scontrol->name);
0951         kfree(scontrol);
0952         return 0;
0953     }
0954 
0955     if (ret < 0) {
0956         kfree(scontrol->name);
0957         kfree(scontrol);
0958         return ret;
0959     }
0960 
0961     scontrol->led_ctl.led_value = -1;
0962 
0963     dobj->private = scontrol;
0964     list_add(&scontrol->list, &sdev->kcontrol_list);
0965     return 0;
0966 }
0967 
0968 static int sof_control_unload(struct snd_soc_component *scomp,
0969                   struct snd_soc_dobj *dobj)
0970 {
0971     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
0972     const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
0973     struct snd_sof_control *scontrol = dobj->private;
0974     int ret = 0;
0975 
0976     dev_dbg(scomp->dev, "tplg: unload control name : %s\n", scontrol->name);
0977 
0978     if (ipc_tplg_ops->control_free) {
0979         ret = ipc_tplg_ops->control_free(sdev, scontrol);
0980         if (ret < 0)
0981             dev_err(scomp->dev, "failed to free control: %s\n", scontrol->name);
0982     }
0983 
0984     /* free all data before returning in case of error too */
0985     kfree(scontrol->ipc_control_data);
0986     kfree(scontrol->priv);
0987     kfree(scontrol->name);
0988     list_del(&scontrol->list);
0989     kfree(scontrol);
0990 
0991     return ret;
0992 }
0993 
0994 /*
0995  * DAI Topology
0996  */
0997 
0998 static int sof_connect_dai_widget(struct snd_soc_component *scomp,
0999                   struct snd_soc_dapm_widget *w,
1000                   struct snd_soc_tplg_dapm_widget *tw,
1001                   struct snd_sof_dai *dai)
1002 {
1003     struct snd_soc_card *card = scomp->card;
1004     struct snd_soc_pcm_runtime *rtd;
1005     struct snd_soc_dai *cpu_dai;
1006     int i;
1007 
1008     if (!w->sname) {
1009         dev_err(scomp->dev, "Widget %s does not have stream\n", w->name);
1010         return -EINVAL;
1011     }
1012 
1013     list_for_each_entry(rtd, &card->rtd_list, list) {
1014         dev_vdbg(scomp->dev, "tplg: check widget: %s stream: %s dai stream: %s\n",
1015              w->name,  w->sname, rtd->dai_link->stream_name);
1016 
1017         /* does stream match DAI link ? */
1018         if (!rtd->dai_link->stream_name ||
1019             strcmp(w->sname, rtd->dai_link->stream_name))
1020             continue;
1021 
1022         switch (w->id) {
1023         case snd_soc_dapm_dai_out:
1024             for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
1025                 /*
1026                  * Please create DAI widget in the right order
1027                  * to ensure BE will connect to the right DAI
1028                  * widget.
1029                  */
1030                 if (!cpu_dai->capture_widget) {
1031                     cpu_dai->capture_widget = w;
1032                     break;
1033                 }
1034             }
1035             if (i == rtd->num_cpus) {
1036                 dev_err(scomp->dev, "error: can't find BE for DAI %s\n",
1037                     w->name);
1038 
1039                 return -EINVAL;
1040             }
1041             dai->name = rtd->dai_link->name;
1042             dev_dbg(scomp->dev, "tplg: connected widget %s -> DAI link %s\n",
1043                 w->name, rtd->dai_link->name);
1044             break;
1045         case snd_soc_dapm_dai_in:
1046             for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
1047                 /*
1048                  * Please create DAI widget in the right order
1049                  * to ensure BE will connect to the right DAI
1050                  * widget.
1051                  */
1052                 if (!cpu_dai->playback_widget) {
1053                     cpu_dai->playback_widget = w;
1054                     break;
1055                 }
1056             }
1057             if (i == rtd->num_cpus) {
1058                 dev_err(scomp->dev, "error: can't find BE for DAI %s\n",
1059                     w->name);
1060 
1061                 return -EINVAL;
1062             }
1063             dai->name = rtd->dai_link->name;
1064             dev_dbg(scomp->dev, "tplg: connected widget %s -> DAI link %s\n",
1065                 w->name, rtd->dai_link->name);
1066             break;
1067         default:
1068             break;
1069         }
1070     }
1071 
1072     /* check we have a connection */
1073     if (!dai->name) {
1074         dev_err(scomp->dev, "error: can't connect DAI %s stream %s\n",
1075             w->name, w->sname);
1076         return -EINVAL;
1077     }
1078 
1079     return 0;
1080 }
1081 
1082 static void sof_disconnect_dai_widget(struct snd_soc_component *scomp,
1083                       struct snd_soc_dapm_widget *w)
1084 {
1085     struct snd_soc_card *card = scomp->card;
1086     struct snd_soc_pcm_runtime *rtd;
1087     struct snd_soc_dai *cpu_dai;
1088     int i;
1089 
1090     if (!w->sname)
1091         return;
1092 
1093     list_for_each_entry(rtd, &card->rtd_list, list) {
1094         /* does stream match DAI link ? */
1095         if (!rtd->dai_link->stream_name ||
1096             strcmp(w->sname, rtd->dai_link->stream_name))
1097             continue;
1098 
1099         switch (w->id) {
1100         case snd_soc_dapm_dai_out:
1101             for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
1102                 if (cpu_dai->capture_widget == w) {
1103                     cpu_dai->capture_widget = NULL;
1104                     break;
1105                 }
1106             }
1107             break;
1108         case snd_soc_dapm_dai_in:
1109             for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
1110                 if (cpu_dai->playback_widget == w) {
1111                     cpu_dai->playback_widget = NULL;
1112                     break;
1113                 }
1114             }
1115             break;
1116         default:
1117             break;
1118         }
1119     }
1120 }
1121 
1122 /* bind PCM ID to host component ID */
1123 static int spcm_bind(struct snd_soc_component *scomp, struct snd_sof_pcm *spcm,
1124              int dir)
1125 {
1126     struct snd_sof_widget *host_widget;
1127 
1128     host_widget = snd_sof_find_swidget_sname(scomp,
1129                          spcm->pcm.caps[dir].name,
1130                          dir);
1131     if (!host_widget) {
1132         dev_err(scomp->dev, "can't find host comp to bind pcm\n");
1133         return -EINVAL;
1134     }
1135 
1136     spcm->stream[dir].comp_id = host_widget->comp_id;
1137 
1138     return 0;
1139 }
1140 
1141 static int sof_get_token_value(u32 token_id, struct snd_sof_tuple *tuples, int num_tuples)
1142 {
1143     int i;
1144 
1145     if (!tuples)
1146         return -EINVAL;
1147 
1148     for (i = 0; i < num_tuples; i++) {
1149         if (tuples[i].token == token_id)
1150             return tuples[i].value.v;
1151     }
1152 
1153     return -EINVAL;
1154 }
1155 
1156 static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_sof_widget *swidget,
1157                    struct snd_soc_tplg_dapm_widget *tw,
1158                    enum sof_tokens *object_token_list, int count)
1159 {
1160     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1161     const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
1162     const struct sof_token_info *token_list = ipc_tplg_ops->token_list;
1163     struct snd_soc_tplg_private *private = &tw->priv;
1164     int num_tuples = 0;
1165     int ret, i;
1166 
1167     if (count > 0 && !object_token_list) {
1168         dev_err(scomp->dev, "No token list for widget %s\n", swidget->widget->name);
1169         return -EINVAL;
1170     }
1171 
1172     /* calculate max size of tuples array */
1173     for (i = 0; i < count; i++)
1174         num_tuples += token_list[object_token_list[i]].count;
1175 
1176     /* allocate memory for tuples array */
1177     swidget->tuples = kcalloc(num_tuples, sizeof(*swidget->tuples), GFP_KERNEL);
1178     if (!swidget->tuples)
1179         return -ENOMEM;
1180 
1181     /* parse token list for widget */
1182     for (i = 0; i < count; i++) {
1183         int num_sets = 1;
1184 
1185         if (object_token_list[i] >= SOF_TOKEN_COUNT) {
1186             dev_err(scomp->dev, "Invalid token id %d for widget %s\n",
1187                 object_token_list[i], swidget->widget->name);
1188             ret = -EINVAL;
1189             goto err;
1190         }
1191 
1192         switch (object_token_list[i]) {
1193         case SOF_COMP_EXT_TOKENS:
1194             /* parse and save UUID in swidget */
1195             ret = sof_parse_tokens(scomp, swidget,
1196                            token_list[object_token_list[i]].tokens,
1197                            token_list[object_token_list[i]].count,
1198                            private->array, le32_to_cpu(private->size));
1199             if (ret < 0) {
1200                 dev_err(scomp->dev, "Failed parsing %s for widget %s\n",
1201                     token_list[object_token_list[i]].name,
1202                     swidget->widget->name);
1203                 goto err;
1204             }
1205 
1206             continue;
1207         case SOF_IN_AUDIO_FORMAT_TOKENS:
1208         case SOF_OUT_AUDIO_FORMAT_TOKENS:
1209         case SOF_COPIER_GATEWAY_CFG_TOKENS:
1210         case SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS:
1211             num_sets = sof_get_token_value(SOF_TKN_COMP_NUM_AUDIO_FORMATS,
1212                                swidget->tuples, swidget->num_tuples);
1213 
1214             if (num_sets < 0) {
1215                 dev_err(sdev->dev, "Invalid audio format count for %s\n",
1216                     swidget->widget->name);
1217                 ret = num_sets;
1218                 goto err;
1219             }
1220 
1221             if (num_sets > 1) {
1222                 struct snd_sof_tuple *new_tuples;
1223 
1224                 num_tuples += token_list[object_token_list[i]].count * num_sets;
1225                 new_tuples = krealloc(swidget->tuples,
1226                               sizeof(*new_tuples) * num_tuples, GFP_KERNEL);
1227                 if (!new_tuples) {
1228                     ret = -ENOMEM;
1229                     goto err;
1230                 }
1231 
1232                 swidget->tuples = new_tuples;
1233             }
1234             break;
1235         default:
1236             break;
1237         }
1238 
1239         /* copy one set of tuples per token ID into swidget->tuples */
1240         ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size),
1241                       object_token_list[i], num_sets, swidget->tuples,
1242                       num_tuples, &swidget->num_tuples);
1243         if (ret < 0) {
1244             dev_err(scomp->dev, "Failed parsing %s for widget %s err: %d\n",
1245                 token_list[object_token_list[i]].name, swidget->widget->name, ret);
1246             goto err;
1247         }
1248     }
1249 
1250     return 0;
1251 err:
1252     kfree(swidget->tuples);
1253     return ret;
1254 }
1255 
1256 /* external widget init - used for any driver specific init */
1257 static int sof_widget_ready(struct snd_soc_component *scomp, int index,
1258                 struct snd_soc_dapm_widget *w,
1259                 struct snd_soc_tplg_dapm_widget *tw)
1260 {
1261     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1262     const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
1263     const struct sof_ipc_tplg_widget_ops *widget_ops = ipc_tplg_ops->widget;
1264     struct snd_sof_widget *swidget;
1265     struct snd_sof_dai *dai;
1266     enum sof_tokens *token_list;
1267     int token_list_size;
1268     int ret = 0;
1269 
1270     swidget = kzalloc(sizeof(*swidget), GFP_KERNEL);
1271     if (!swidget)
1272         return -ENOMEM;
1273 
1274     swidget->scomp = scomp;
1275     swidget->widget = w;
1276     swidget->comp_id = sdev->next_comp_id++;
1277     swidget->complete = 0;
1278     swidget->id = w->id;
1279     swidget->pipeline_id = index;
1280     swidget->private = NULL;
1281 
1282     dev_dbg(scomp->dev, "tplg: ready widget id %d pipe %d type %d name : %s stream %s\n",
1283         swidget->comp_id, index, swidget->id, tw->name,
1284         strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0
1285             ? tw->sname : "none");
1286 
1287     token_list = widget_ops[w->id].token_list;
1288     token_list_size = widget_ops[w->id].token_list_size;
1289 
1290     /* handle any special case widgets */
1291     switch (w->id) {
1292     case snd_soc_dapm_dai_in:
1293     case snd_soc_dapm_dai_out:
1294         dai = kzalloc(sizeof(*dai), GFP_KERNEL);
1295         if (!dai) {
1296             kfree(swidget);
1297             return -ENOMEM;
1298 
1299         }
1300 
1301         ret = sof_widget_parse_tokens(scomp, swidget, tw, token_list, token_list_size);
1302         if (!ret)
1303             ret = sof_connect_dai_widget(scomp, w, tw, dai);
1304         if (ret < 0) {
1305             kfree(dai);
1306             break;
1307         }
1308         list_add(&dai->list, &sdev->dai_list);
1309         swidget->private = dai;
1310         break;
1311     case snd_soc_dapm_effect:
1312         /* check we have some tokens - we need at least process type */
1313         if (le32_to_cpu(tw->priv.size) == 0) {
1314             dev_err(scomp->dev, "error: process tokens not found\n");
1315             ret = -EINVAL;
1316             break;
1317         }
1318         ret = sof_widget_parse_tokens(scomp, swidget, tw, token_list, token_list_size);
1319         break;
1320     case snd_soc_dapm_pga:
1321         if (!le32_to_cpu(tw->num_kcontrols)) {
1322             dev_err(scomp->dev, "invalid kcontrol count %d for volume\n",
1323                 tw->num_kcontrols);
1324             ret = -EINVAL;
1325             break;
1326         }
1327 
1328         fallthrough;
1329     case snd_soc_dapm_mixer:
1330     case snd_soc_dapm_buffer:
1331     case snd_soc_dapm_scheduler:
1332     case snd_soc_dapm_aif_out:
1333     case snd_soc_dapm_aif_in:
1334     case snd_soc_dapm_src:
1335     case snd_soc_dapm_asrc:
1336     case snd_soc_dapm_siggen:
1337     case snd_soc_dapm_mux:
1338     case snd_soc_dapm_demux:
1339         ret = sof_widget_parse_tokens(scomp, swidget, tw,  token_list, token_list_size);
1340         break;
1341     case snd_soc_dapm_switch:
1342     case snd_soc_dapm_dai_link:
1343     case snd_soc_dapm_kcontrol:
1344     default:
1345         dev_dbg(scomp->dev, "widget type %d name %s not handled\n", swidget->id, tw->name);
1346         break;
1347     }
1348 
1349     if (sof_debug_check_flag(SOF_DBG_DISABLE_MULTICORE)) {
1350         swidget->core = SOF_DSP_PRIMARY_CORE;
1351     } else {
1352         int core = sof_get_token_value(SOF_TKN_COMP_CORE_ID, swidget->tuples,
1353                            swidget->num_tuples);
1354 
1355         if (core >= 0)
1356             swidget->core = core;
1357     }
1358 
1359     /* check token parsing reply */
1360     if (ret < 0) {
1361         dev_err(scomp->dev,
1362             "error: failed to add widget id %d type %d name : %s stream %s\n",
1363             tw->shift, swidget->id, tw->name,
1364             strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0
1365                 ? tw->sname : "none");
1366         kfree(swidget);
1367         return ret;
1368     }
1369 
1370     /* bind widget to external event */
1371     if (tw->event_type) {
1372         if (widget_ops[w->id].bind_event) {
1373             ret = widget_ops[w->id].bind_event(scomp, swidget,
1374                                le16_to_cpu(tw->event_type));
1375             if (ret) {
1376                 dev_err(scomp->dev, "widget event binding failed for %s\n",
1377                     swidget->widget->name);
1378                 kfree(swidget->private);
1379                 kfree(swidget->tuples);
1380                 kfree(swidget);
1381                 return ret;
1382             }
1383         }
1384     }
1385 
1386     w->dobj.private = swidget;
1387     list_add(&swidget->list, &sdev->widget_list);
1388     return ret;
1389 }
1390 
1391 static int sof_route_unload(struct snd_soc_component *scomp,
1392                 struct snd_soc_dobj *dobj)
1393 {
1394     struct snd_sof_route *sroute;
1395 
1396     sroute = dobj->private;
1397     if (!sroute)
1398         return 0;
1399 
1400     /* free sroute and its private data */
1401     kfree(sroute->private);
1402     list_del(&sroute->list);
1403     kfree(sroute);
1404 
1405     return 0;
1406 }
1407 
1408 static int sof_widget_unload(struct snd_soc_component *scomp,
1409                  struct snd_soc_dobj *dobj)
1410 {
1411     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1412     const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
1413     const struct sof_ipc_tplg_widget_ops *widget_ops = ipc_tplg_ops->widget;
1414     const struct snd_kcontrol_new *kc;
1415     struct snd_soc_dapm_widget *widget;
1416     struct snd_sof_control *scontrol;
1417     struct snd_sof_widget *swidget;
1418     struct soc_mixer_control *sm;
1419     struct soc_bytes_ext *sbe;
1420     struct snd_sof_dai *dai;
1421     struct soc_enum *se;
1422     int i;
1423 
1424     swidget = dobj->private;
1425     if (!swidget)
1426         return 0;
1427 
1428     widget = swidget->widget;
1429 
1430     switch (swidget->id) {
1431     case snd_soc_dapm_dai_in:
1432     case snd_soc_dapm_dai_out:
1433         dai = swidget->private;
1434 
1435         if (dai)
1436             list_del(&dai->list);
1437 
1438         sof_disconnect_dai_widget(scomp, widget);
1439 
1440         break;
1441     default:
1442         break;
1443     }
1444     for (i = 0; i < widget->num_kcontrols; i++) {
1445         kc = &widget->kcontrol_news[i];
1446         switch (widget->dobj.widget.kcontrol_type[i]) {
1447         case SND_SOC_TPLG_TYPE_MIXER:
1448             sm = (struct soc_mixer_control *)kc->private_value;
1449             scontrol = sm->dobj.private;
1450             if (sm->max > 1)
1451                 kfree(scontrol->volume_table);
1452             break;
1453         case SND_SOC_TPLG_TYPE_ENUM:
1454             se = (struct soc_enum *)kc->private_value;
1455             scontrol = se->dobj.private;
1456             break;
1457         case SND_SOC_TPLG_TYPE_BYTES:
1458             sbe = (struct soc_bytes_ext *)kc->private_value;
1459             scontrol = sbe->dobj.private;
1460             break;
1461         default:
1462             dev_warn(scomp->dev, "unsupported kcontrol_type\n");
1463             goto out;
1464         }
1465         kfree(scontrol->ipc_control_data);
1466         list_del(&scontrol->list);
1467         kfree(scontrol->name);
1468         kfree(scontrol);
1469     }
1470 
1471 out:
1472     /* free IPC related data */
1473     if (widget_ops[swidget->id].ipc_free)
1474         widget_ops[swidget->id].ipc_free(swidget);
1475 
1476     kfree(swidget->tuples);
1477 
1478     /* remove and free swidget object */
1479     list_del(&swidget->list);
1480     kfree(swidget);
1481 
1482     return 0;
1483 }
1484 
1485 /*
1486  * DAI HW configuration.
1487  */
1488 
1489 /* FE DAI - used for any driver specific init */
1490 static int sof_dai_load(struct snd_soc_component *scomp, int index,
1491             struct snd_soc_dai_driver *dai_drv,
1492             struct snd_soc_tplg_pcm *pcm, struct snd_soc_dai *dai)
1493 {
1494     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1495     struct snd_soc_tplg_stream_caps *caps;
1496     struct snd_soc_tplg_private *private = &pcm->priv;
1497     struct snd_sof_pcm *spcm;
1498     int stream;
1499     int ret;
1500 
1501     /* nothing to do for BEs atm */
1502     if (!pcm)
1503         return 0;
1504 
1505     spcm = kzalloc(sizeof(*spcm), GFP_KERNEL);
1506     if (!spcm)
1507         return -ENOMEM;
1508 
1509     spcm->scomp = scomp;
1510 
1511     for_each_pcm_streams(stream) {
1512         spcm->stream[stream].comp_id = COMP_ID_UNASSIGNED;
1513         if (pcm->compress)
1514             snd_sof_compr_init_elapsed_work(&spcm->stream[stream].period_elapsed_work);
1515         else
1516             snd_sof_pcm_init_elapsed_work(&spcm->stream[stream].period_elapsed_work);
1517     }
1518 
1519     spcm->pcm = *pcm;
1520     dev_dbg(scomp->dev, "tplg: load pcm %s\n", pcm->dai_name);
1521 
1522     dai_drv->dobj.private = spcm;
1523     list_add(&spcm->list, &sdev->pcm_list);
1524 
1525     ret = sof_parse_tokens(scomp, spcm, stream_tokens,
1526                    ARRAY_SIZE(stream_tokens), private->array,
1527                    le32_to_cpu(private->size));
1528     if (ret) {
1529         dev_err(scomp->dev, "error: parse stream tokens failed %d\n",
1530             le32_to_cpu(private->size));
1531         return ret;
1532     }
1533 
1534     /* do we need to allocate playback PCM DMA pages */
1535     if (!spcm->pcm.playback)
1536         goto capture;
1537 
1538     stream = SNDRV_PCM_STREAM_PLAYBACK;
1539 
1540     dev_vdbg(scomp->dev, "tplg: pcm %s stream tokens: playback d0i3:%d\n",
1541          spcm->pcm.pcm_name, spcm->stream[stream].d0i3_compatible);
1542 
1543     caps = &spcm->pcm.caps[stream];
1544 
1545     /* allocate playback page table buffer */
1546     ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev,
1547                   PAGE_SIZE, &spcm->stream[stream].page_table);
1548     if (ret < 0) {
1549         dev_err(scomp->dev, "error: can't alloc page table for %s %d\n",
1550             caps->name, ret);
1551 
1552         return ret;
1553     }
1554 
1555     /* bind pcm to host comp */
1556     ret = spcm_bind(scomp, spcm, stream);
1557     if (ret) {
1558         dev_err(scomp->dev,
1559             "error: can't bind pcm to host\n");
1560         goto free_playback_tables;
1561     }
1562 
1563 capture:
1564     stream = SNDRV_PCM_STREAM_CAPTURE;
1565 
1566     /* do we need to allocate capture PCM DMA pages */
1567     if (!spcm->pcm.capture)
1568         return ret;
1569 
1570     dev_vdbg(scomp->dev, "tplg: pcm %s stream tokens: capture d0i3:%d\n",
1571          spcm->pcm.pcm_name, spcm->stream[stream].d0i3_compatible);
1572 
1573     caps = &spcm->pcm.caps[stream];
1574 
1575     /* allocate capture page table buffer */
1576     ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev,
1577                   PAGE_SIZE, &spcm->stream[stream].page_table);
1578     if (ret < 0) {
1579         dev_err(scomp->dev, "error: can't alloc page table for %s %d\n",
1580             caps->name, ret);
1581         goto free_playback_tables;
1582     }
1583 
1584     /* bind pcm to host comp */
1585     ret = spcm_bind(scomp, spcm, stream);
1586     if (ret) {
1587         dev_err(scomp->dev,
1588             "error: can't bind pcm to host\n");
1589         snd_dma_free_pages(&spcm->stream[stream].page_table);
1590         goto free_playback_tables;
1591     }
1592 
1593     return ret;
1594 
1595 free_playback_tables:
1596     if (spcm->pcm.playback)
1597         snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_PLAYBACK].page_table);
1598 
1599     return ret;
1600 }
1601 
1602 static int sof_dai_unload(struct snd_soc_component *scomp,
1603               struct snd_soc_dobj *dobj)
1604 {
1605     struct snd_sof_pcm *spcm = dobj->private;
1606 
1607     /* free PCM DMA pages */
1608     if (spcm->pcm.playback)
1609         snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_PLAYBACK].page_table);
1610 
1611     if (spcm->pcm.capture)
1612         snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_CAPTURE].page_table);
1613 
1614     /* remove from list and free spcm */
1615     list_del(&spcm->list);
1616     kfree(spcm);
1617 
1618     return 0;
1619 }
1620 
1621 static const struct sof_topology_token common_dai_link_tokens[] = {
1622     {SOF_TKN_DAI_TYPE, SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_dai_type,
1623         offsetof(struct snd_sof_dai_link, type)},
1624 };
1625 
1626 /* DAI link - used for any driver specific init */
1627 static int sof_link_load(struct snd_soc_component *scomp, int index, struct snd_soc_dai_link *link,
1628              struct snd_soc_tplg_link_config *cfg)
1629 {
1630     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1631     const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
1632     const struct sof_token_info *token_list = ipc_tplg_ops->token_list;
1633     struct snd_soc_tplg_private *private = &cfg->priv;
1634     struct snd_sof_dai_link *slink;
1635     u32 token_id = 0;
1636     int num_tuples = 0;
1637     int ret, num_sets;
1638 
1639     if (!link->platforms) {
1640         dev_err(scomp->dev, "error: no platforms\n");
1641         return -EINVAL;
1642     }
1643     link->platforms->name = dev_name(scomp->dev);
1644 
1645     /*
1646      * Set nonatomic property for FE dai links as their trigger action
1647      * involves IPC's.
1648      */
1649     if (!link->no_pcm) {
1650         link->nonatomic = true;
1651 
1652         /*
1653          * set default trigger order for all links. Exceptions to
1654          * the rule will be handled in sof_pcm_dai_link_fixup()
1655          * For playback, the sequence is the following: start FE,
1656          * start BE, stop BE, stop FE; for Capture the sequence is
1657          * inverted start BE, start FE, stop FE, stop BE
1658          */
1659         link->trigger[SNDRV_PCM_STREAM_PLAYBACK] =
1660                     SND_SOC_DPCM_TRIGGER_PRE;
1661         link->trigger[SNDRV_PCM_STREAM_CAPTURE] =
1662                     SND_SOC_DPCM_TRIGGER_POST;
1663 
1664         /* nothing more to do for FE dai links */
1665         return 0;
1666     }
1667 
1668     /* check we have some tokens - we need at least DAI type */
1669     if (le32_to_cpu(private->size) == 0) {
1670         dev_err(scomp->dev, "error: expected tokens for DAI, none found\n");
1671         return -EINVAL;
1672     }
1673 
1674     slink = kzalloc(sizeof(*slink), GFP_KERNEL);
1675     if (!slink)
1676         return -ENOMEM;
1677 
1678     slink->num_hw_configs = le32_to_cpu(cfg->num_hw_configs);
1679     slink->hw_configs = kmemdup(cfg->hw_config,
1680                     sizeof(*slink->hw_configs) * slink->num_hw_configs,
1681                     GFP_KERNEL);
1682     if (!slink->hw_configs) {
1683         kfree(slink);
1684         return -ENOMEM;
1685     }
1686 
1687     slink->default_hw_cfg_id = le32_to_cpu(cfg->default_hw_config_id);
1688     slink->link = link;
1689 
1690     dev_dbg(scomp->dev, "tplg: %d hw_configs found, default id: %d for dai link %s!\n",
1691         slink->num_hw_configs, slink->default_hw_cfg_id, link->name);
1692 
1693     ret = sof_parse_tokens(scomp, slink, common_dai_link_tokens,
1694                    ARRAY_SIZE(common_dai_link_tokens),
1695                    private->array, le32_to_cpu(private->size));
1696     if (ret < 0) {
1697         dev_err(scomp->dev, "Failed tp parse common DAI link tokens\n");
1698         kfree(slink->hw_configs);
1699         kfree(slink);
1700         return ret;
1701     }
1702 
1703     if (!token_list)
1704         goto out;
1705 
1706     /* calculate size of tuples array */
1707     num_tuples += token_list[SOF_DAI_LINK_TOKENS].count;
1708     num_sets = slink->num_hw_configs;
1709     switch (slink->type) {
1710     case SOF_DAI_INTEL_SSP:
1711         token_id = SOF_SSP_TOKENS;
1712         num_tuples += token_list[SOF_SSP_TOKENS].count * slink->num_hw_configs;
1713         break;
1714     case SOF_DAI_INTEL_DMIC:
1715         token_id = SOF_DMIC_TOKENS;
1716         num_tuples += token_list[SOF_DMIC_TOKENS].count;
1717 
1718         /* Allocate memory for max PDM controllers */
1719         num_tuples += token_list[SOF_DMIC_PDM_TOKENS].count * SOF_DAI_INTEL_DMIC_NUM_CTRL;
1720         break;
1721     case SOF_DAI_INTEL_HDA:
1722         token_id = SOF_HDA_TOKENS;
1723         num_tuples += token_list[SOF_HDA_TOKENS].count;
1724         break;
1725     case SOF_DAI_INTEL_ALH:
1726         token_id = SOF_ALH_TOKENS;
1727         num_tuples += token_list[SOF_ALH_TOKENS].count;
1728         break;
1729     case SOF_DAI_IMX_SAI:
1730         token_id = SOF_SAI_TOKENS;
1731         num_tuples += token_list[SOF_SAI_TOKENS].count;
1732         break;
1733     case SOF_DAI_IMX_ESAI:
1734         token_id = SOF_ESAI_TOKENS;
1735         num_tuples += token_list[SOF_ESAI_TOKENS].count;
1736         break;
1737     case SOF_DAI_MEDIATEK_AFE:
1738         token_id = SOF_AFE_TOKENS;
1739         num_tuples += token_list[SOF_AFE_TOKENS].count;
1740         break;
1741     case SOF_DAI_AMD_DMIC:
1742         token_id = SOF_ACPDMIC_TOKENS;
1743         num_tuples += token_list[SOF_ACPDMIC_TOKENS].count;
1744         break;
1745     default:
1746         break;
1747     }
1748 
1749     /* allocate memory for tuples array */
1750     slink->tuples = kcalloc(num_tuples, sizeof(*slink->tuples), GFP_KERNEL);
1751     if (!slink->tuples) {
1752         kfree(slink->hw_configs);
1753         kfree(slink);
1754         return -ENOMEM;
1755     }
1756 
1757     if (token_list[SOF_DAI_LINK_TOKENS].tokens) {
1758         /* parse one set of DAI link tokens */
1759         ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size),
1760                       SOF_DAI_LINK_TOKENS, 1, slink->tuples,
1761                       num_tuples, &slink->num_tuples);
1762         if (ret < 0) {
1763             dev_err(scomp->dev, "failed to parse %s for dai link %s\n",
1764                 token_list[SOF_DAI_LINK_TOKENS].name, link->name);
1765             goto err;
1766         }
1767     }
1768 
1769     /* nothing more to do if there are no DAI type-specific tokens defined */
1770     if (!token_id || !token_list[token_id].tokens)
1771         goto out;
1772 
1773     /* parse "num_sets" sets of DAI-specific tokens */
1774     ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size),
1775                   token_id, num_sets, slink->tuples, num_tuples, &slink->num_tuples);
1776     if (ret < 0) {
1777         dev_err(scomp->dev, "failed to parse %s for dai link %s\n",
1778             token_list[token_id].name, link->name);
1779         goto err;
1780     }
1781 
1782     /* for DMIC, also parse all sets of DMIC PDM tokens based on active PDM count */
1783     if (token_id == SOF_DMIC_TOKENS) {
1784         num_sets = sof_get_token_value(SOF_TKN_INTEL_DMIC_NUM_PDM_ACTIVE,
1785                            slink->tuples, slink->num_tuples);
1786 
1787         if (num_sets < 0) {
1788             dev_err(sdev->dev, "Invalid active PDM count for %s\n", link->name);
1789             ret = num_sets;
1790             goto err;
1791         }
1792 
1793         ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size),
1794                       SOF_DMIC_PDM_TOKENS, num_sets, slink->tuples,
1795                       num_tuples, &slink->num_tuples);
1796         if (ret < 0) {
1797             dev_err(scomp->dev, "failed to parse %s for dai link %s\n",
1798                 token_list[SOF_DMIC_PDM_TOKENS].name, link->name);
1799             goto err;
1800         }
1801     }
1802 out:
1803     link->dobj.private = slink;
1804     list_add(&slink->list, &sdev->dai_link_list);
1805 
1806     return 0;
1807 
1808 err:
1809     kfree(slink->tuples);
1810     kfree(slink->hw_configs);
1811     kfree(slink);
1812 
1813     return ret;
1814 }
1815 
1816 static int sof_link_unload(struct snd_soc_component *scomp, struct snd_soc_dobj *dobj)
1817 {
1818     struct snd_sof_dai_link *slink = dobj->private;
1819 
1820     if (!slink)
1821         return 0;
1822 
1823     kfree(slink->tuples);
1824     list_del(&slink->list);
1825     kfree(slink->hw_configs);
1826     kfree(slink);
1827     dobj->private = NULL;
1828 
1829     return 0;
1830 }
1831 
1832 /* DAI link - used for any driver specific init */
1833 static int sof_route_load(struct snd_soc_component *scomp, int index,
1834               struct snd_soc_dapm_route *route)
1835 {
1836     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1837     struct snd_sof_widget *source_swidget, *sink_swidget;
1838     struct snd_soc_dobj *dobj = &route->dobj;
1839     struct snd_sof_route *sroute;
1840     int ret = 0;
1841 
1842     /* allocate memory for sroute and connect */
1843     sroute = kzalloc(sizeof(*sroute), GFP_KERNEL);
1844     if (!sroute)
1845         return -ENOMEM;
1846 
1847     sroute->scomp = scomp;
1848     dev_dbg(scomp->dev, "sink %s control %s source %s\n",
1849         route->sink, route->control ? route->control : "none",
1850         route->source);
1851 
1852     /* source component */
1853     source_swidget = snd_sof_find_swidget(scomp, (char *)route->source);
1854     if (!source_swidget) {
1855         dev_err(scomp->dev, "error: source %s not found\n",
1856             route->source);
1857         ret = -EINVAL;
1858         goto err;
1859     }
1860 
1861     /*
1862      * Virtual widgets of type output/out_drv may be added in topology
1863      * for compatibility. These are not handled by the FW.
1864      * So, don't send routes whose source/sink widget is of such types
1865      * to the DSP.
1866      */
1867     if (source_swidget->id == snd_soc_dapm_out_drv ||
1868         source_swidget->id == snd_soc_dapm_output)
1869         goto err;
1870 
1871     /* sink component */
1872     sink_swidget = snd_sof_find_swidget(scomp, (char *)route->sink);
1873     if (!sink_swidget) {
1874         dev_err(scomp->dev, "error: sink %s not found\n",
1875             route->sink);
1876         ret = -EINVAL;
1877         goto err;
1878     }
1879 
1880     /*
1881      * Don't send routes whose sink widget is of type
1882      * output or out_drv to the DSP
1883      */
1884     if (sink_swidget->id == snd_soc_dapm_out_drv ||
1885         sink_swidget->id == snd_soc_dapm_output)
1886         goto err;
1887 
1888     sroute->route = route;
1889     dobj->private = sroute;
1890     sroute->src_widget = source_swidget;
1891     sroute->sink_widget = sink_swidget;
1892 
1893     /* add route to route list */
1894     list_add(&sroute->list, &sdev->route_list);
1895 
1896     return 0;
1897 err:
1898     kfree(sroute);
1899     return ret;
1900 }
1901 
1902 /**
1903  * sof_set_pipe_widget - Set pipe_widget for a component
1904  * @sdev: pointer to struct snd_sof_dev
1905  * @pipe_widget: pointer to struct snd_sof_widget of type snd_soc_dapm_scheduler
1906  * @swidget: pointer to struct snd_sof_widget that has the same pipeline ID as @pipe_widget
1907  *
1908  * Return: 0 if successful, -EINVAL on error.
1909  * The function checks if @swidget is associated with any volatile controls. If so, setting
1910  * the dynamic_pipeline_widget is disallowed.
1911  */
1912 static int sof_set_pipe_widget(struct snd_sof_dev *sdev, struct snd_sof_widget *pipe_widget,
1913                    struct snd_sof_widget *swidget)
1914 {
1915     struct snd_sof_control *scontrol;
1916 
1917     if (pipe_widget->dynamic_pipeline_widget) {
1918         /* dynamic widgets cannot have volatile kcontrols */
1919         list_for_each_entry(scontrol, &sdev->kcontrol_list, list)
1920             if (scontrol->comp_id == swidget->comp_id &&
1921                 (scontrol->access & SNDRV_CTL_ELEM_ACCESS_VOLATILE)) {
1922                 dev_err(sdev->dev,
1923                     "error: volatile control found for dynamic widget %s\n",
1924                     swidget->widget->name);
1925                 return -EINVAL;
1926             }
1927     }
1928 
1929     /* set the pipe_widget and apply the dynamic_pipeline_widget_flag */
1930     swidget->pipe_widget = pipe_widget;
1931     swidget->dynamic_pipeline_widget = pipe_widget->dynamic_pipeline_widget;
1932 
1933     return 0;
1934 }
1935 
1936 /* completion - called at completion of firmware loading */
1937 static int sof_complete(struct snd_soc_component *scomp)
1938 {
1939     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1940     struct snd_sof_widget *swidget, *comp_swidget;
1941     const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
1942     const struct sof_ipc_tplg_widget_ops *widget_ops = ipc_tplg_ops->widget;
1943     struct snd_sof_control *scontrol;
1944     int ret;
1945 
1946     /* first update all control IPC structures based on the IPC version */
1947     if (ipc_tplg_ops->control_setup)
1948         list_for_each_entry(scontrol, &sdev->kcontrol_list, list) {
1949             ret = ipc_tplg_ops->control_setup(sdev, scontrol);
1950             if (ret < 0) {
1951                 dev_err(sdev->dev, "failed updating IPC struct for control %s\n",
1952                     scontrol->name);
1953                 return ret;
1954             }
1955         }
1956 
1957     /*
1958      * then update all widget IPC structures. If any of the ipc_setup callbacks fail, the
1959      * topology will be removed and all widgets will be unloaded resulting in freeing all
1960      * associated memories.
1961      */
1962     list_for_each_entry(swidget, &sdev->widget_list, list) {
1963         if (widget_ops[swidget->id].ipc_setup) {
1964             ret = widget_ops[swidget->id].ipc_setup(swidget);
1965             if (ret < 0) {
1966                 dev_err(sdev->dev, "failed updating IPC struct for %s\n",
1967                     swidget->widget->name);
1968                 return ret;
1969             }
1970         }
1971     }
1972 
1973     /* set the pipe_widget and apply the dynamic_pipeline_widget_flag */
1974     list_for_each_entry(swidget, &sdev->widget_list, list) {
1975         switch (swidget->id) {
1976         case snd_soc_dapm_scheduler:
1977             /*
1978              * Apply the dynamic_pipeline_widget flag and set the pipe_widget field
1979              * for all widgets that have the same pipeline ID as the scheduler widget
1980              */
1981             list_for_each_entry(comp_swidget, &sdev->widget_list, list)
1982                 if (comp_swidget->pipeline_id == swidget->pipeline_id) {
1983                     ret = sof_set_pipe_widget(sdev, swidget, comp_swidget);
1984                     if (ret < 0)
1985                         return ret;
1986                 }
1987             break;
1988         default:
1989             break;
1990         }
1991     }
1992 
1993     /* verify topology components loading including dynamic pipelines */
1994     if (sof_debug_check_flag(SOF_DBG_VERIFY_TPLG)) {
1995         if (ipc_tplg_ops->set_up_all_pipelines && ipc_tplg_ops->tear_down_all_pipelines) {
1996             ret = ipc_tplg_ops->set_up_all_pipelines(sdev, true);
1997             if (ret < 0) {
1998                 dev_err(sdev->dev, "Failed to set up all topology pipelines: %d\n",
1999                     ret);
2000                 return ret;
2001             }
2002 
2003             ret = ipc_tplg_ops->tear_down_all_pipelines(sdev, true);
2004             if (ret < 0) {
2005                 dev_err(sdev->dev, "Failed to tear down topology pipelines: %d\n",
2006                     ret);
2007                 return ret;
2008             }
2009         }
2010     }
2011 
2012     /* set up static pipelines */
2013     if (ipc_tplg_ops->set_up_all_pipelines)
2014         return ipc_tplg_ops->set_up_all_pipelines(sdev, false);
2015 
2016     return 0;
2017 }
2018 
2019 /* manifest - optional to inform component of manifest */
2020 static int sof_manifest(struct snd_soc_component *scomp, int index,
2021             struct snd_soc_tplg_manifest *man)
2022 {
2023     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
2024     const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
2025 
2026     if (ipc_tplg_ops->parse_manifest)
2027         return ipc_tplg_ops->parse_manifest(scomp, index, man);
2028 
2029     return 0;
2030 }
2031 
2032 /* vendor specific kcontrol handlers available for binding */
2033 static const struct snd_soc_tplg_kcontrol_ops sof_io_ops[] = {
2034     {SOF_TPLG_KCTL_VOL_ID, snd_sof_volume_get, snd_sof_volume_put},
2035     {SOF_TPLG_KCTL_BYTES_ID, snd_sof_bytes_get, snd_sof_bytes_put},
2036     {SOF_TPLG_KCTL_ENUM_ID, snd_sof_enum_get, snd_sof_enum_put},
2037     {SOF_TPLG_KCTL_SWITCH_ID, snd_sof_switch_get, snd_sof_switch_put},
2038 };
2039 
2040 /* vendor specific bytes ext handlers available for binding */
2041 static const struct snd_soc_tplg_bytes_ext_ops sof_bytes_ext_ops[] = {
2042     {SOF_TPLG_KCTL_BYTES_ID, snd_sof_bytes_ext_get, snd_sof_bytes_ext_put},
2043     {SOF_TPLG_KCTL_BYTES_VOLATILE_RO, snd_sof_bytes_ext_volatile_get},
2044 };
2045 
2046 static struct snd_soc_tplg_ops sof_tplg_ops = {
2047     /* external kcontrol init - used for any driver specific init */
2048     .control_load   = sof_control_load,
2049     .control_unload = sof_control_unload,
2050 
2051     /* external kcontrol init - used for any driver specific init */
2052     .dapm_route_load    = sof_route_load,
2053     .dapm_route_unload  = sof_route_unload,
2054 
2055     /* external widget init - used for any driver specific init */
2056     /* .widget_load is not currently used */
2057     .widget_ready   = sof_widget_ready,
2058     .widget_unload  = sof_widget_unload,
2059 
2060     /* FE DAI - used for any driver specific init */
2061     .dai_load   = sof_dai_load,
2062     .dai_unload = sof_dai_unload,
2063 
2064     /* DAI link - used for any driver specific init */
2065     .link_load  = sof_link_load,
2066     .link_unload    = sof_link_unload,
2067 
2068     /* completion - called at completion of firmware loading */
2069     .complete   = sof_complete,
2070 
2071     /* manifest - optional to inform component of manifest */
2072     .manifest   = sof_manifest,
2073 
2074     /* vendor specific kcontrol handlers available for binding */
2075     .io_ops     = sof_io_ops,
2076     .io_ops_count   = ARRAY_SIZE(sof_io_ops),
2077 
2078     /* vendor specific bytes ext handlers available for binding */
2079     .bytes_ext_ops  = sof_bytes_ext_ops,
2080     .bytes_ext_ops_count    = ARRAY_SIZE(sof_bytes_ext_ops),
2081 };
2082 
2083 int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
2084 {
2085     struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
2086     const struct firmware *fw;
2087     int ret;
2088 
2089     dev_dbg(scomp->dev, "loading topology:%s\n", file);
2090 
2091     ret = request_firmware(&fw, file, scomp->dev);
2092     if (ret < 0) {
2093         dev_err(scomp->dev, "error: tplg request firmware %s failed err: %d\n",
2094             file, ret);
2095         dev_err(scomp->dev,
2096             "you may need to download the firmware from https://github.com/thesofproject/sof-bin/\n");
2097         return ret;
2098     }
2099 
2100     ret = snd_soc_tplg_component_load(scomp, &sof_tplg_ops, fw);
2101     if (ret < 0) {
2102         dev_err(scomp->dev, "error: tplg component load failed %d\n",
2103             ret);
2104         ret = -EINVAL;
2105     }
2106 
2107     release_firmware(fw);
2108 
2109     if (ret >= 0 && sdev->led_present)
2110         ret = snd_ctl_led_request();
2111 
2112     return ret;
2113 }
2114 EXPORT_SYMBOL(snd_sof_load_topology);