0001
0002
0003
0004
0005
0006
0007
0008
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
0025
0026
0027 #define VOL_TWENTIETH_ROOT_OF_TEN 73533
0028
0029 #define VOL_FORTIETH_ROOT_OF_TEN 69419
0030
0031
0032 #define VOL_HALF_DB_STEP 50
0033
0034
0035 #define TLV_MIN 0
0036 #define TLV_STEP 1
0037 #define TLV_MUTE 2
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
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
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
0121 if (!(num_tokens_matched % token_instance_num))
0122 break;
0123
0124
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
0136 if ((int)p[SNDRV_CTL_TLVO_TYPE] != SNDRV_CTL_TLVT_DB_SCALE)
0137 return -EINVAL;
0138
0139
0140 tlv[TLV_MIN] = (int)p[SNDRV_CTL_TLVO_DB_SCALE_MIN] / 100;
0141
0142
0143 tlv[TLV_STEP] = (int)(p[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] &
0144 TLV_DB_SCALE_MASK);
0145
0146
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
0158
0159
0160
0161 static inline u32 vol_shift_64(u64 i, u32 x)
0162 {
0163
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
0175
0176
0177
0178
0179
0180
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
0189 if (exp == 0)
0190 return power;
0191
0192
0193 if (exp < 0)
0194 iter = exp * -1;
0195 else
0196 iter = exp;
0197
0198
0199 for (i = 0; i < iter; i++) {
0200
0201
0202
0203
0204 power = vol_shift_64((u64)power * a, fwl);
0205 }
0206
0207 if (exp > 0) {
0208
0209 return power;
0210 }
0211
0212
0213 numerator = (u64)1 << (fwl << 1);
0214 do_div(numerator, power);
0215
0216 return (u32)numerator;
0217 }
0218
0219
0220
0221
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
0230 if (value == 0 && tlv[TLV_MUTE])
0231 return 0;
0232
0233
0234
0235
0236
0237 dB_gain = tlv[TLV_MIN] + (value * tlv[TLV_STEP]) / 100;
0238
0239
0240
0241
0242
0243 linear_gain = vol_pow32(VOL_TWENTIETH_ROOT_OF_TEN, dB_gain, VOLUME_FWL);
0244
0245
0246 f_step = tlv[TLV_STEP] - (tlv[TLV_STEP] / 100);
0247
0248
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
0259
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
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
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
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
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
0396
0397
0398
0399
0400
0401
0402
0403
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
0415 for (i = 0; i < le32_to_cpu(array->num_elems); i++) {
0416 elem = &array->uuid[i];
0417
0418
0419 for (j = 0; j < num_tokens; j++) {
0420
0421 if (tokens[j].type != SND_SOC_TPLG_TUPLE_TYPE_UUID)
0422 continue;
0423
0424
0425 if (tokens[j].token != le32_to_cpu(elem->token))
0426 continue;
0427
0428
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
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
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
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
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
0492 if (asize < 0) {
0493 dev_err(sdev->dev, "Invalid array size 0x%x\n", asize);
0494 return -EINVAL;
0495 }
0496
0497
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
0505 for (i = 0; i < le32_to_cpu(array->num_elems); i++) {
0506
0507 for (j = 0; j < num_tokens; j++) {
0508
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
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
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
0544 if (*num_copied_tuples == tuples_size)
0545 return 0;
0546 }
0547 }
0548
0549
0550 array = (struct snd_soc_tplg_vendor_array *)((u8 *)array + asize);
0551 }
0552
0553 return 0;
0554 }
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565
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
0577 for (i = 0; i < le32_to_cpu(array->num_elems); i++) {
0578 elem = &array->string[i];
0579
0580
0581 for (j = 0; j < num_tokens; j++) {
0582
0583 if (tokens[j].type != SND_SOC_TPLG_TUPLE_TYPE_STRING)
0584 continue;
0585
0586
0587 if (tokens[j].token != le32_to_cpu(elem->token))
0588 continue;
0589
0590
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
0602
0603
0604
0605
0606
0607
0608
0609
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
0621 for (i = 0; i < le32_to_cpu(array->num_elems); i++) {
0622 elem = &array->value[i];
0623
0624
0625 for (j = 0; j < num_tokens; j++) {
0626
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
0634 if (tokens[j].token != le32_to_cpu(elem->token))
0635 continue;
0636
0637
0638 tokens[j].get_token(elem, object, offset + tokens[j].offset);
0639
0640 found++;
0641 }
0642 }
0643
0644 return found;
0645 }
0646
0647
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
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
0676 if (asize < 0) {
0677 dev_err(scomp->dev, "error: invalid array size 0x%x\n",
0678 asize);
0679 return -EINVAL;
0680 }
0681
0682
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
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
0714 array = (struct snd_soc_tplg_vendor_array *)((u8 *)array
0715 + asize);
0716
0717
0718 if (found >= count) {
0719 offset += object_size;
0720 total += found;
0721 found = 0;
0722 }
0723 }
0724
0725 return 0;
0726 }
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736
0737
0738
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
0748
0749
0750
0751
0752 return sof_parse_token_sets(scomp, object, tokens, num_tokens, array,
0753 array_size, 1, 0);
0754 }
0755
0756
0757
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
0773 if (le32_to_cpu(mc->num_channels) > SND_SOC_TPLG_MAX_CHAN)
0774 return -EINVAL;
0775
0776
0777
0778
0779
0780
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
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
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
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
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
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
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
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
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
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
1027
1028
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
1049
1050
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
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
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
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
1173 for (i = 0; i < count; i++)
1174 num_tuples += token_list[object_token_list[i]].count;
1175
1176
1177 swidget->tuples = kcalloc(num_tuples, sizeof(*swidget->tuples), GFP_KERNEL);
1178 if (!swidget->tuples)
1179 return -ENOMEM;
1180
1181
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
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
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
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
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
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
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
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
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
1473 if (widget_ops[swidget->id].ipc_free)
1474 widget_ops[swidget->id].ipc_free(swidget);
1475
1476 kfree(swidget->tuples);
1477
1478
1479 list_del(&swidget->list);
1480 kfree(swidget);
1481
1482 return 0;
1483 }
1484
1485
1486
1487
1488
1489
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
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
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
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
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
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
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
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
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
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
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
1647
1648
1649 if (!link->no_pcm) {
1650 link->nonatomic = true;
1651
1652
1653
1654
1655
1656
1657
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
1665 return 0;
1666 }
1667
1668
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
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
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
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
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
1770 if (!token_id || !token_list[token_id].tokens)
1771 goto out;
1772
1773
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
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
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
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
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
1863
1864
1865
1866
1867 if (source_swidget->id == snd_soc_dapm_out_drv ||
1868 source_swidget->id == snd_soc_dapm_output)
1869 goto err;
1870
1871
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
1882
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
1894 list_add(&sroute->list, &sdev->route_list);
1895
1896 return 0;
1897 err:
1898 kfree(sroute);
1899 return ret;
1900 }
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
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
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
1930 swidget->pipe_widget = pipe_widget;
1931 swidget->dynamic_pipeline_widget = pipe_widget->dynamic_pipeline_widget;
1932
1933 return 0;
1934 }
1935
1936
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
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
1959
1960
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
1974 list_for_each_entry(swidget, &sdev->widget_list, list) {
1975 switch (swidget->id) {
1976 case snd_soc_dapm_scheduler:
1977
1978
1979
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
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
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
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
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
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
2048 .control_load = sof_control_load,
2049 .control_unload = sof_control_unload,
2050
2051
2052 .dapm_route_load = sof_route_load,
2053 .dapm_route_unload = sof_route_unload,
2054
2055
2056
2057 .widget_ready = sof_widget_ready,
2058 .widget_unload = sof_widget_unload,
2059
2060
2061 .dai_load = sof_dai_load,
2062 .dai_unload = sof_dai_unload,
2063
2064
2065 .link_load = sof_link_load,
2066 .link_unload = sof_link_unload,
2067
2068
2069 .complete = sof_complete,
2070
2071
2072 .manifest = sof_manifest,
2073
2074
2075 .io_ops = sof_io_ops,
2076 .io_ops_count = ARRAY_SIZE(sof_io_ops),
2077
2078
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);