1 /* 2 * soc-topology.c -- ALSA SoC Topology 3 * 4 * Copyright (C) 2012 Texas Instruments Inc. 5 * Copyright (C) 2015 Intel Corporation. 6 * 7 * Authors: Liam Girdwood <liam.r.girdwood@linux.intel.com> 8 * K, Mythri P <mythri.p.k@intel.com> 9 * Prusty, Subhransu S <subhransu.s.prusty@intel.com> 10 * B, Jayachandran <jayachandran.b@intel.com> 11 * Abdullah, Omair M <omair.m.abdullah@intel.com> 12 * Jin, Yao <yao.jin@intel.com> 13 * Lin, Mengdong <mengdong.lin@intel.com> 14 * 15 * This program is free software; you can redistribute it and/or modify it 16 * under the terms of the GNU General Public License as published by the 17 * Free Software Foundation; either version 2 of the License, or (at your 18 * option) any later version. 19 * 20 * Add support to read audio firmware topology alongside firmware text. The 21 * topology data can contain kcontrols, DAPM graphs, widgets, DAIs, DAI links, 22 * equalizers, firmware, coefficients etc. 23 * 24 * This file only manages the core ALSA and ASoC components, all other bespoke 25 * firmware topology data is passed to component drivers for bespoke handling. 26 */ 27 28 #include <linux/kernel.h> 29 #include <linux/export.h> 30 #include <linux/list.h> 31 #include <linux/firmware.h> 32 #include <linux/slab.h> 33 #include <sound/soc.h> 34 #include <sound/soc-dapm.h> 35 #include <sound/soc-topology.h> 36 #include <sound/tlv.h> 37 38 /* 39 * We make several passes over the data (since it wont necessarily be ordered) 40 * and process objects in the following order. This guarantees the component 41 * drivers will be ready with any vendor data before the mixers and DAPM objects 42 * are loaded (that may make use of the vendor data). 43 */ 44 #define SOC_TPLG_PASS_MANIFEST 0 45 #define SOC_TPLG_PASS_VENDOR 1 46 #define SOC_TPLG_PASS_MIXER 2 47 #define SOC_TPLG_PASS_WIDGET 3 48 #define SOC_TPLG_PASS_GRAPH 4 49 #define SOC_TPLG_PASS_PINS 5 50 #define SOC_TPLG_PASS_PCM_DAI 6 51 52 #define SOC_TPLG_PASS_START SOC_TPLG_PASS_MANIFEST 53 #define SOC_TPLG_PASS_END SOC_TPLG_PASS_PCM_DAI 54 55 struct soc_tplg { 56 const struct firmware *fw; 57 58 /* runtime FW parsing */ 59 const u8 *pos; /* read postion */ 60 const u8 *hdr_pos; /* header position */ 61 unsigned int pass; /* pass number */ 62 63 /* component caller */ 64 struct device *dev; 65 struct snd_soc_component *comp; 66 u32 index; /* current block index */ 67 u32 req_index; /* required index, only loaded/free matching blocks */ 68 69 /* kcontrol operations */ 70 const struct snd_soc_tplg_kcontrol_ops *io_ops; 71 int io_ops_count; 72 73 /* optional fw loading callbacks to component drivers */ 74 struct snd_soc_tplg_ops *ops; 75 }; 76 77 static int soc_tplg_process_headers(struct soc_tplg *tplg); 78 static void soc_tplg_complete(struct soc_tplg *tplg); 79 struct snd_soc_dapm_widget * 80 snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm, 81 const struct snd_soc_dapm_widget *widget); 82 struct snd_soc_dapm_widget * 83 snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, 84 const struct snd_soc_dapm_widget *widget); 85 86 /* check we dont overflow the data for this control chunk */ 87 static int soc_tplg_check_elem_count(struct soc_tplg *tplg, size_t elem_size, 88 unsigned int count, size_t bytes, const char *elem_type) 89 { 90 const u8 *end = tplg->pos + elem_size * count; 91 92 if (end > tplg->fw->data + tplg->fw->size) { 93 dev_err(tplg->dev, "ASoC: %s overflow end of data\n", 94 elem_type); 95 return -EINVAL; 96 } 97 98 /* check there is enough room in chunk for control. 99 extra bytes at the end of control are for vendor data here */ 100 if (elem_size * count > bytes) { 101 dev_err(tplg->dev, 102 "ASoC: %s count %d of size %zu is bigger than chunk %zu\n", 103 elem_type, count, elem_size, bytes); 104 return -EINVAL; 105 } 106 107 return 0; 108 } 109 110 static inline int soc_tplg_is_eof(struct soc_tplg *tplg) 111 { 112 const u8 *end = tplg->hdr_pos; 113 114 if (end >= tplg->fw->data + tplg->fw->size) 115 return 1; 116 return 0; 117 } 118 119 static inline unsigned long soc_tplg_get_hdr_offset(struct soc_tplg *tplg) 120 { 121 return (unsigned long)(tplg->hdr_pos - tplg->fw->data); 122 } 123 124 static inline unsigned long soc_tplg_get_offset(struct soc_tplg *tplg) 125 { 126 return (unsigned long)(tplg->pos - tplg->fw->data); 127 } 128 129 /* mapping of Kcontrol types and associated operations. */ 130 static const struct snd_soc_tplg_kcontrol_ops io_ops[] = { 131 {SND_SOC_TPLG_CTL_VOLSW, snd_soc_get_volsw, 132 snd_soc_put_volsw, snd_soc_info_volsw}, 133 {SND_SOC_TPLG_CTL_VOLSW_SX, snd_soc_get_volsw_sx, 134 snd_soc_put_volsw_sx, NULL}, 135 {SND_SOC_TPLG_CTL_ENUM, snd_soc_get_enum_double, 136 snd_soc_put_enum_double, snd_soc_info_enum_double}, 137 {SND_SOC_TPLG_CTL_ENUM_VALUE, snd_soc_get_enum_double, 138 snd_soc_put_enum_double, NULL}, 139 {SND_SOC_TPLG_CTL_BYTES, snd_soc_bytes_get, 140 snd_soc_bytes_put, snd_soc_bytes_info}, 141 {SND_SOC_TPLG_CTL_RANGE, snd_soc_get_volsw_range, 142 snd_soc_put_volsw_range, snd_soc_info_volsw_range}, 143 {SND_SOC_TPLG_CTL_VOLSW_XR_SX, snd_soc_get_xr_sx, 144 snd_soc_put_xr_sx, snd_soc_info_xr_sx}, 145 {SND_SOC_TPLG_CTL_STROBE, snd_soc_get_strobe, 146 snd_soc_put_strobe, NULL}, 147 {SND_SOC_TPLG_DAPM_CTL_VOLSW, snd_soc_dapm_get_volsw, 148 snd_soc_dapm_put_volsw, snd_soc_info_volsw}, 149 {SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE, snd_soc_dapm_get_enum_double, 150 snd_soc_dapm_put_enum_double, snd_soc_info_enum_double}, 151 {SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT, snd_soc_dapm_get_enum_double, 152 snd_soc_dapm_put_enum_double, NULL}, 153 {SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE, snd_soc_dapm_get_enum_double, 154 snd_soc_dapm_put_enum_double, NULL}, 155 {SND_SOC_TPLG_DAPM_CTL_PIN, snd_soc_dapm_get_pin_switch, 156 snd_soc_dapm_put_pin_switch, snd_soc_dapm_info_pin_switch}, 157 }; 158 159 struct soc_tplg_map { 160 int uid; 161 int kid; 162 }; 163 164 /* mapping of widget types from UAPI IDs to kernel IDs */ 165 static const struct soc_tplg_map dapm_map[] = { 166 {SND_SOC_TPLG_DAPM_INPUT, snd_soc_dapm_input}, 167 {SND_SOC_TPLG_DAPM_OUTPUT, snd_soc_dapm_output}, 168 {SND_SOC_TPLG_DAPM_MUX, snd_soc_dapm_mux}, 169 {SND_SOC_TPLG_DAPM_MIXER, snd_soc_dapm_mixer}, 170 {SND_SOC_TPLG_DAPM_PGA, snd_soc_dapm_pga}, 171 {SND_SOC_TPLG_DAPM_OUT_DRV, snd_soc_dapm_out_drv}, 172 {SND_SOC_TPLG_DAPM_ADC, snd_soc_dapm_adc}, 173 {SND_SOC_TPLG_DAPM_DAC, snd_soc_dapm_dac}, 174 {SND_SOC_TPLG_DAPM_SWITCH, snd_soc_dapm_switch}, 175 {SND_SOC_TPLG_DAPM_PRE, snd_soc_dapm_pre}, 176 {SND_SOC_TPLG_DAPM_POST, snd_soc_dapm_post}, 177 {SND_SOC_TPLG_DAPM_AIF_IN, snd_soc_dapm_aif_in}, 178 {SND_SOC_TPLG_DAPM_AIF_OUT, snd_soc_dapm_aif_out}, 179 {SND_SOC_TPLG_DAPM_DAI_IN, snd_soc_dapm_dai_in}, 180 {SND_SOC_TPLG_DAPM_DAI_OUT, snd_soc_dapm_dai_out}, 181 {SND_SOC_TPLG_DAPM_DAI_LINK, snd_soc_dapm_dai_link}, 182 }; 183 184 static int tplc_chan_get_reg(struct soc_tplg *tplg, 185 struct snd_soc_tplg_channel *chan, int map) 186 { 187 int i; 188 189 for (i = 0; i < SND_SOC_TPLG_MAX_CHAN; i++) { 190 if (chan[i].id == map) 191 return chan[i].reg; 192 } 193 194 return -EINVAL; 195 } 196 197 static int tplc_chan_get_shift(struct soc_tplg *tplg, 198 struct snd_soc_tplg_channel *chan, int map) 199 { 200 int i; 201 202 for (i = 0; i < SND_SOC_TPLG_MAX_CHAN; i++) { 203 if (chan[i].id == map) 204 return chan[i].shift; 205 } 206 207 return -EINVAL; 208 } 209 210 static int get_widget_id(int tplg_type) 211 { 212 int i; 213 214 for (i = 0; i < ARRAY_SIZE(dapm_map); i++) { 215 if (tplg_type == dapm_map[i].uid) 216 return dapm_map[i].kid; 217 } 218 219 return -EINVAL; 220 } 221 222 static enum snd_soc_dobj_type get_dobj_mixer_type( 223 struct snd_soc_tplg_ctl_hdr *control_hdr) 224 { 225 if (control_hdr == NULL) 226 return SND_SOC_DOBJ_NONE; 227 228 switch (control_hdr->ops.info) { 229 case SND_SOC_TPLG_CTL_VOLSW: 230 case SND_SOC_TPLG_CTL_VOLSW_SX: 231 case SND_SOC_TPLG_CTL_VOLSW_XR_SX: 232 case SND_SOC_TPLG_CTL_RANGE: 233 case SND_SOC_TPLG_CTL_STROBE: 234 return SND_SOC_DOBJ_MIXER; 235 case SND_SOC_TPLG_CTL_ENUM: 236 case SND_SOC_TPLG_CTL_ENUM_VALUE: 237 return SND_SOC_DOBJ_ENUM; 238 case SND_SOC_TPLG_CTL_BYTES: 239 return SND_SOC_DOBJ_BYTES; 240 default: 241 return SND_SOC_DOBJ_NONE; 242 } 243 } 244 245 static enum snd_soc_dobj_type get_dobj_type(struct snd_soc_tplg_hdr *hdr, 246 struct snd_soc_tplg_ctl_hdr *control_hdr) 247 { 248 switch (hdr->type) { 249 case SND_SOC_TPLG_TYPE_MIXER: 250 return get_dobj_mixer_type(control_hdr); 251 case SND_SOC_TPLG_TYPE_DAPM_GRAPH: 252 case SND_SOC_TPLG_TYPE_MANIFEST: 253 return SND_SOC_DOBJ_NONE; 254 case SND_SOC_TPLG_TYPE_DAPM_WIDGET: 255 return SND_SOC_DOBJ_WIDGET; 256 case SND_SOC_TPLG_TYPE_DAI_LINK: 257 return SND_SOC_DOBJ_DAI_LINK; 258 case SND_SOC_TPLG_TYPE_PCM: 259 return SND_SOC_DOBJ_PCM; 260 case SND_SOC_TPLG_TYPE_CODEC_LINK: 261 return SND_SOC_DOBJ_CODEC_LINK; 262 default: 263 return SND_SOC_DOBJ_NONE; 264 } 265 } 266 267 static inline void soc_bind_err(struct soc_tplg *tplg, 268 struct snd_soc_tplg_ctl_hdr *hdr, int index) 269 { 270 dev_err(tplg->dev, 271 "ASoC: invalid control type (g,p,i) %d:%d:%d index %d at 0x%lx\n", 272 hdr->ops.get, hdr->ops.put, hdr->ops.info, index, 273 soc_tplg_get_offset(tplg)); 274 } 275 276 static inline void soc_control_err(struct soc_tplg *tplg, 277 struct snd_soc_tplg_ctl_hdr *hdr, const char *name) 278 { 279 dev_err(tplg->dev, 280 "ASoC: no complete mixer IO handler for %s type (g,p,i) %d:%d:%d at 0x%lx\n", 281 name, hdr->ops.get, hdr->ops.put, hdr->ops.info, 282 soc_tplg_get_offset(tplg)); 283 } 284 285 /* pass vendor data to component driver for processing */ 286 static int soc_tplg_vendor_load_(struct soc_tplg *tplg, 287 struct snd_soc_tplg_hdr *hdr) 288 { 289 int ret = 0; 290 291 if (tplg->comp && tplg->ops && tplg->ops->vendor_load) 292 ret = tplg->ops->vendor_load(tplg->comp, hdr); 293 else { 294 dev_err(tplg->dev, "ASoC: no vendor load callback for ID %d\n", 295 hdr->vendor_type); 296 return -EINVAL; 297 } 298 299 if (ret < 0) 300 dev_err(tplg->dev, 301 "ASoC: vendor load failed at hdr offset %ld/0x%lx for type %d:%d\n", 302 soc_tplg_get_hdr_offset(tplg), 303 soc_tplg_get_hdr_offset(tplg), 304 hdr->type, hdr->vendor_type); 305 return ret; 306 } 307 308 /* pass vendor data to component driver for processing */ 309 static int soc_tplg_vendor_load(struct soc_tplg *tplg, 310 struct snd_soc_tplg_hdr *hdr) 311 { 312 if (tplg->pass != SOC_TPLG_PASS_VENDOR) 313 return 0; 314 315 return soc_tplg_vendor_load_(tplg, hdr); 316 } 317 318 /* optionally pass new dynamic widget to component driver. This is mainly for 319 * external widgets where we can assign private data/ops */ 320 static int soc_tplg_widget_load(struct soc_tplg *tplg, 321 struct snd_soc_dapm_widget *w, struct snd_soc_tplg_dapm_widget *tplg_w) 322 { 323 if (tplg->comp && tplg->ops && tplg->ops->widget_load) 324 return tplg->ops->widget_load(tplg->comp, w, tplg_w); 325 326 return 0; 327 } 328 329 /* pass dynamic FEs configurations to component driver */ 330 static int soc_tplg_pcm_dai_load(struct soc_tplg *tplg, 331 struct snd_soc_tplg_pcm_dai *pcm_dai, int num_pcm_dai) 332 { 333 if (tplg->comp && tplg->ops && tplg->ops->pcm_dai_load) 334 return tplg->ops->pcm_dai_load(tplg->comp, pcm_dai, num_pcm_dai); 335 336 return 0; 337 } 338 339 /* tell the component driver that all firmware has been loaded in this request */ 340 static void soc_tplg_complete(struct soc_tplg *tplg) 341 { 342 if (tplg->comp && tplg->ops && tplg->ops->complete) 343 tplg->ops->complete(tplg->comp); 344 } 345 346 /* add a dynamic kcontrol */ 347 static int soc_tplg_add_dcontrol(struct snd_card *card, struct device *dev, 348 const struct snd_kcontrol_new *control_new, const char *prefix, 349 void *data, struct snd_kcontrol **kcontrol) 350 { 351 int err; 352 353 *kcontrol = snd_soc_cnew(control_new, data, control_new->name, prefix); 354 if (*kcontrol == NULL) { 355 dev_err(dev, "ASoC: Failed to create new kcontrol %s\n", 356 control_new->name); 357 return -ENOMEM; 358 } 359 360 err = snd_ctl_add(card, *kcontrol); 361 if (err < 0) { 362 dev_err(dev, "ASoC: Failed to add %s: %d\n", 363 control_new->name, err); 364 return err; 365 } 366 367 return 0; 368 } 369 370 /* add a dynamic kcontrol for component driver */ 371 static int soc_tplg_add_kcontrol(struct soc_tplg *tplg, 372 struct snd_kcontrol_new *k, struct snd_kcontrol **kcontrol) 373 { 374 struct snd_soc_component *comp = tplg->comp; 375 376 return soc_tplg_add_dcontrol(comp->card->snd_card, 377 comp->dev, k, NULL, comp, kcontrol); 378 } 379 380 /* remove a mixer kcontrol */ 381 static void remove_mixer(struct snd_soc_component *comp, 382 struct snd_soc_dobj *dobj, int pass) 383 { 384 struct snd_card *card = comp->card->snd_card; 385 struct soc_mixer_control *sm = 386 container_of(dobj, struct soc_mixer_control, dobj); 387 const unsigned int *p = NULL; 388 389 if (pass != SOC_TPLG_PASS_MIXER) 390 return; 391 392 if (dobj->ops && dobj->ops->control_unload) 393 dobj->ops->control_unload(comp, dobj); 394 395 if (sm->dobj.control.kcontrol->tlv.p) 396 p = sm->dobj.control.kcontrol->tlv.p; 397 snd_ctl_remove(card, sm->dobj.control.kcontrol); 398 list_del(&sm->dobj.list); 399 kfree(sm); 400 kfree(p); 401 } 402 403 /* remove an enum kcontrol */ 404 static void remove_enum(struct snd_soc_component *comp, 405 struct snd_soc_dobj *dobj, int pass) 406 { 407 struct snd_card *card = comp->card->snd_card; 408 struct soc_enum *se = container_of(dobj, struct soc_enum, dobj); 409 int i; 410 411 if (pass != SOC_TPLG_PASS_MIXER) 412 return; 413 414 if (dobj->ops && dobj->ops->control_unload) 415 dobj->ops->control_unload(comp, dobj); 416 417 snd_ctl_remove(card, se->dobj.control.kcontrol); 418 list_del(&se->dobj.list); 419 420 kfree(se->dobj.control.dvalues); 421 for (i = 0; i < se->items; i++) 422 kfree(se->dobj.control.dtexts[i]); 423 kfree(se); 424 } 425 426 /* remove a byte kcontrol */ 427 static void remove_bytes(struct snd_soc_component *comp, 428 struct snd_soc_dobj *dobj, int pass) 429 { 430 struct snd_card *card = comp->card->snd_card; 431 struct soc_bytes_ext *sb = 432 container_of(dobj, struct soc_bytes_ext, dobj); 433 434 if (pass != SOC_TPLG_PASS_MIXER) 435 return; 436 437 if (dobj->ops && dobj->ops->control_unload) 438 dobj->ops->control_unload(comp, dobj); 439 440 snd_ctl_remove(card, sb->dobj.control.kcontrol); 441 list_del(&sb->dobj.list); 442 kfree(sb); 443 } 444 445 /* remove a widget and it's kcontrols - routes must be removed first */ 446 static void remove_widget(struct snd_soc_component *comp, 447 struct snd_soc_dobj *dobj, int pass) 448 { 449 struct snd_card *card = comp->card->snd_card; 450 struct snd_soc_dapm_widget *w = 451 container_of(dobj, struct snd_soc_dapm_widget, dobj); 452 int i; 453 454 if (pass != SOC_TPLG_PASS_WIDGET) 455 return; 456 457 if (dobj->ops && dobj->ops->widget_unload) 458 dobj->ops->widget_unload(comp, dobj); 459 460 /* 461 * Dynamic Widgets either have 1 enum kcontrol or 1..N mixers. 462 * The enum may either have an array of values or strings. 463 */ 464 if (dobj->widget.kcontrol_enum) { 465 /* enumerated widget mixer */ 466 struct soc_enum *se = 467 (struct soc_enum *)w->kcontrols[0]->private_value; 468 469 snd_ctl_remove(card, w->kcontrols[0]); 470 471 kfree(se->dobj.control.dvalues); 472 for (i = 0; i < se->items; i++) 473 kfree(se->dobj.control.dtexts[i]); 474 475 kfree(se); 476 kfree(w->kcontrol_news); 477 } else { 478 /* non enumerated widget mixer */ 479 for (i = 0; i < w->num_kcontrols; i++) { 480 struct snd_kcontrol *kcontrol = w->kcontrols[i]; 481 struct soc_mixer_control *sm = 482 (struct soc_mixer_control *) kcontrol->private_value; 483 484 kfree(w->kcontrols[i]->tlv.p); 485 486 snd_ctl_remove(card, w->kcontrols[i]); 487 kfree(sm); 488 } 489 kfree(w->kcontrol_news); 490 } 491 /* widget w is freed by soc-dapm.c */ 492 } 493 494 /* remove PCM DAI configurations */ 495 static void remove_pcm_dai(struct snd_soc_component *comp, 496 struct snd_soc_dobj *dobj, int pass) 497 { 498 if (pass != SOC_TPLG_PASS_PCM_DAI) 499 return; 500 501 if (dobj->ops && dobj->ops->pcm_dai_unload) 502 dobj->ops->pcm_dai_unload(comp, dobj); 503 504 list_del(&dobj->list); 505 kfree(dobj); 506 } 507 508 /* bind a kcontrol to it's IO handlers */ 509 static int soc_tplg_kcontrol_bind_io(struct snd_soc_tplg_ctl_hdr *hdr, 510 struct snd_kcontrol_new *k, 511 const struct snd_soc_tplg_kcontrol_ops *ops, int num_ops, 512 const struct snd_soc_tplg_kcontrol_ops *bops, int num_bops) 513 { 514 int i; 515 516 /* try and map standard kcontrols handler first */ 517 for (i = 0; i < num_ops; i++) { 518 519 if (ops[i].id == hdr->ops.put) 520 k->put = ops[i].put; 521 if (ops[i].id == hdr->ops.get) 522 k->get = ops[i].get; 523 if (ops[i].id == hdr->ops.info) 524 k->info = ops[i].info; 525 } 526 527 /* standard handlers found ? */ 528 if (k->put && k->get && k->info) 529 return 0; 530 531 /* none found so try bespoke handlers */ 532 for (i = 0; i < num_bops; i++) { 533 534 if (k->put == NULL && bops[i].id == hdr->ops.put) 535 k->put = bops[i].put; 536 if (k->get == NULL && bops[i].id == hdr->ops.get) 537 k->get = bops[i].get; 538 if (k->info == NULL && bops[i].id == hdr->ops.info) 539 k->info = bops[i].info; 540 } 541 542 /* bespoke handlers found ? */ 543 if (k->put && k->get && k->info) 544 return 0; 545 546 /* nothing to bind */ 547 return -EINVAL; 548 } 549 550 /* bind a widgets to it's evnt handlers */ 551 int snd_soc_tplg_widget_bind_event(struct snd_soc_dapm_widget *w, 552 const struct snd_soc_tplg_widget_events *events, 553 int num_events, u16 event_type) 554 { 555 int i; 556 557 w->event = NULL; 558 559 for (i = 0; i < num_events; i++) { 560 if (event_type == events[i].type) { 561 562 /* found - so assign event */ 563 w->event = events[i].event_handler; 564 return 0; 565 } 566 } 567 568 /* not found */ 569 return -EINVAL; 570 } 571 EXPORT_SYMBOL_GPL(snd_soc_tplg_widget_bind_event); 572 573 /* optionally pass new dynamic kcontrol to component driver. */ 574 static int soc_tplg_init_kcontrol(struct soc_tplg *tplg, 575 struct snd_kcontrol_new *k, struct snd_soc_tplg_ctl_hdr *hdr) 576 { 577 if (tplg->comp && tplg->ops && tplg->ops->control_load) 578 return tplg->ops->control_load(tplg->comp, k, hdr); 579 580 return 0; 581 } 582 583 584 static int soc_tplg_create_tlv_db_scale(struct soc_tplg *tplg, 585 struct snd_kcontrol_new *kc, struct snd_soc_tplg_tlv_dbscale *scale) 586 { 587 unsigned int item_len = 2 * sizeof(unsigned int); 588 unsigned int *p; 589 590 p = kzalloc(item_len + 2 * sizeof(unsigned int), GFP_KERNEL); 591 if (!p) 592 return -ENOMEM; 593 594 p[0] = SNDRV_CTL_TLVT_DB_SCALE; 595 p[1] = item_len; 596 p[2] = scale->min; 597 p[3] = (scale->step & TLV_DB_SCALE_MASK) 598 | (scale->mute ? TLV_DB_SCALE_MUTE : 0); 599 600 kc->tlv.p = (void *)p; 601 return 0; 602 } 603 604 static int soc_tplg_create_tlv(struct soc_tplg *tplg, 605 struct snd_kcontrol_new *kc, struct snd_soc_tplg_ctl_hdr *tc) 606 { 607 struct snd_soc_tplg_ctl_tlv *tplg_tlv; 608 609 if (!(tc->access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE)) 610 return 0; 611 612 if (tc->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) { 613 kc->tlv.c = snd_soc_bytes_tlv_callback; 614 } else { 615 tplg_tlv = &tc->tlv; 616 switch (tplg_tlv->type) { 617 case SNDRV_CTL_TLVT_DB_SCALE: 618 return soc_tplg_create_tlv_db_scale(tplg, kc, 619 &tplg_tlv->scale); 620 621 /* TODO: add support for other TLV types */ 622 default: 623 dev_dbg(tplg->dev, "Unsupported TLV type %d\n", 624 tplg_tlv->type); 625 return -EINVAL; 626 } 627 } 628 629 return 0; 630 } 631 632 static inline void soc_tplg_free_tlv(struct soc_tplg *tplg, 633 struct snd_kcontrol_new *kc) 634 { 635 kfree(kc->tlv.p); 636 } 637 638 static int soc_tplg_dbytes_create(struct soc_tplg *tplg, unsigned int count, 639 size_t size) 640 { 641 struct snd_soc_tplg_bytes_control *be; 642 struct soc_bytes_ext *sbe; 643 struct snd_kcontrol_new kc; 644 int i, err; 645 646 if (soc_tplg_check_elem_count(tplg, 647 sizeof(struct snd_soc_tplg_bytes_control), count, 648 size, "mixer bytes")) { 649 dev_err(tplg->dev, "ASoC: Invalid count %d for byte control\n", 650 count); 651 return -EINVAL; 652 } 653 654 for (i = 0; i < count; i++) { 655 be = (struct snd_soc_tplg_bytes_control *)tplg->pos; 656 657 /* validate kcontrol */ 658 if (strnlen(be->hdr.name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == 659 SNDRV_CTL_ELEM_ID_NAME_MAXLEN) 660 return -EINVAL; 661 662 sbe = kzalloc(sizeof(*sbe), GFP_KERNEL); 663 if (sbe == NULL) 664 return -ENOMEM; 665 666 tplg->pos += (sizeof(struct snd_soc_tplg_bytes_control) + 667 be->priv.size); 668 669 dev_dbg(tplg->dev, 670 "ASoC: adding bytes kcontrol %s with access 0x%x\n", 671 be->hdr.name, be->hdr.access); 672 673 memset(&kc, 0, sizeof(kc)); 674 kc.name = be->hdr.name; 675 kc.private_value = (long)sbe; 676 kc.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 677 kc.access = be->hdr.access; 678 679 sbe->max = be->max; 680 sbe->dobj.type = SND_SOC_DOBJ_BYTES; 681 sbe->dobj.ops = tplg->ops; 682 INIT_LIST_HEAD(&sbe->dobj.list); 683 684 /* map io handlers */ 685 err = soc_tplg_kcontrol_bind_io(&be->hdr, &kc, io_ops, 686 ARRAY_SIZE(io_ops), tplg->io_ops, tplg->io_ops_count); 687 if (err) { 688 soc_control_err(tplg, &be->hdr, be->hdr.name); 689 kfree(sbe); 690 continue; 691 } 692 693 /* pass control to driver for optional further init */ 694 err = soc_tplg_init_kcontrol(tplg, &kc, 695 (struct snd_soc_tplg_ctl_hdr *)be); 696 if (err < 0) { 697 dev_err(tplg->dev, "ASoC: failed to init %s\n", 698 be->hdr.name); 699 kfree(sbe); 700 continue; 701 } 702 703 /* register control here */ 704 err = soc_tplg_add_kcontrol(tplg, &kc, 705 &sbe->dobj.control.kcontrol); 706 if (err < 0) { 707 dev_err(tplg->dev, "ASoC: failed to add %s\n", 708 be->hdr.name); 709 kfree(sbe); 710 continue; 711 } 712 713 list_add(&sbe->dobj.list, &tplg->comp->dobj_list); 714 } 715 return 0; 716 717 } 718 719 static int soc_tplg_dmixer_create(struct soc_tplg *tplg, unsigned int count, 720 size_t size) 721 { 722 struct snd_soc_tplg_mixer_control *mc; 723 struct soc_mixer_control *sm; 724 struct snd_kcontrol_new kc; 725 int i, err; 726 727 if (soc_tplg_check_elem_count(tplg, 728 sizeof(struct snd_soc_tplg_mixer_control), 729 count, size, "mixers")) { 730 731 dev_err(tplg->dev, "ASoC: invalid count %d for controls\n", 732 count); 733 return -EINVAL; 734 } 735 736 for (i = 0; i < count; i++) { 737 mc = (struct snd_soc_tplg_mixer_control *)tplg->pos; 738 739 /* validate kcontrol */ 740 if (strnlen(mc->hdr.name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == 741 SNDRV_CTL_ELEM_ID_NAME_MAXLEN) 742 return -EINVAL; 743 744 sm = kzalloc(sizeof(*sm), GFP_KERNEL); 745 if (sm == NULL) 746 return -ENOMEM; 747 tplg->pos += (sizeof(struct snd_soc_tplg_mixer_control) + 748 mc->priv.size); 749 750 dev_dbg(tplg->dev, 751 "ASoC: adding mixer kcontrol %s with access 0x%x\n", 752 mc->hdr.name, mc->hdr.access); 753 754 memset(&kc, 0, sizeof(kc)); 755 kc.name = mc->hdr.name; 756 kc.private_value = (long)sm; 757 kc.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 758 kc.access = mc->hdr.access; 759 760 /* we only support FL/FR channel mapping atm */ 761 sm->reg = tplc_chan_get_reg(tplg, mc->channel, 762 SNDRV_CHMAP_FL); 763 sm->rreg = tplc_chan_get_reg(tplg, mc->channel, 764 SNDRV_CHMAP_FR); 765 sm->shift = tplc_chan_get_shift(tplg, mc->channel, 766 SNDRV_CHMAP_FL); 767 sm->rshift = tplc_chan_get_shift(tplg, mc->channel, 768 SNDRV_CHMAP_FR); 769 770 sm->max = mc->max; 771 sm->min = mc->min; 772 sm->invert = mc->invert; 773 sm->platform_max = mc->platform_max; 774 sm->dobj.index = tplg->index; 775 sm->dobj.ops = tplg->ops; 776 sm->dobj.type = SND_SOC_DOBJ_MIXER; 777 INIT_LIST_HEAD(&sm->dobj.list); 778 779 /* map io handlers */ 780 err = soc_tplg_kcontrol_bind_io(&mc->hdr, &kc, io_ops, 781 ARRAY_SIZE(io_ops), tplg->io_ops, tplg->io_ops_count); 782 if (err) { 783 soc_control_err(tplg, &mc->hdr, mc->hdr.name); 784 kfree(sm); 785 continue; 786 } 787 788 /* pass control to driver for optional further init */ 789 err = soc_tplg_init_kcontrol(tplg, &kc, 790 (struct snd_soc_tplg_ctl_hdr *) mc); 791 if (err < 0) { 792 dev_err(tplg->dev, "ASoC: failed to init %s\n", 793 mc->hdr.name); 794 kfree(sm); 795 continue; 796 } 797 798 /* create any TLV data */ 799 soc_tplg_create_tlv(tplg, &kc, &mc->hdr); 800 801 /* register control here */ 802 err = soc_tplg_add_kcontrol(tplg, &kc, 803 &sm->dobj.control.kcontrol); 804 if (err < 0) { 805 dev_err(tplg->dev, "ASoC: failed to add %s\n", 806 mc->hdr.name); 807 soc_tplg_free_tlv(tplg, &kc); 808 kfree(sm); 809 continue; 810 } 811 812 list_add(&sm->dobj.list, &tplg->comp->dobj_list); 813 } 814 815 return 0; 816 } 817 818 static int soc_tplg_denum_create_texts(struct soc_enum *se, 819 struct snd_soc_tplg_enum_control *ec) 820 { 821 int i, ret; 822 823 se->dobj.control.dtexts = 824 kzalloc(sizeof(char *) * ec->items, GFP_KERNEL); 825 if (se->dobj.control.dtexts == NULL) 826 return -ENOMEM; 827 828 for (i = 0; i < ec->items; i++) { 829 830 if (strnlen(ec->texts[i], SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == 831 SNDRV_CTL_ELEM_ID_NAME_MAXLEN) { 832 ret = -EINVAL; 833 goto err; 834 } 835 836 se->dobj.control.dtexts[i] = kstrdup(ec->texts[i], GFP_KERNEL); 837 if (!se->dobj.control.dtexts[i]) { 838 ret = -ENOMEM; 839 goto err; 840 } 841 } 842 843 return 0; 844 845 err: 846 for (--i; i >= 0; i--) 847 kfree(se->dobj.control.dtexts[i]); 848 kfree(se->dobj.control.dtexts); 849 return ret; 850 } 851 852 static int soc_tplg_denum_create_values(struct soc_enum *se, 853 struct snd_soc_tplg_enum_control *ec) 854 { 855 if (ec->items > sizeof(*ec->values)) 856 return -EINVAL; 857 858 se->dobj.control.dvalues = 859 kmalloc(ec->items * sizeof(u32), GFP_KERNEL); 860 if (!se->dobj.control.dvalues) 861 return -ENOMEM; 862 863 memcpy(se->dobj.control.dvalues, ec->values, ec->items * sizeof(u32)); 864 return 0; 865 } 866 867 static int soc_tplg_denum_create(struct soc_tplg *tplg, unsigned int count, 868 size_t size) 869 { 870 struct snd_soc_tplg_enum_control *ec; 871 struct soc_enum *se; 872 struct snd_kcontrol_new kc; 873 int i, ret, err; 874 875 if (soc_tplg_check_elem_count(tplg, 876 sizeof(struct snd_soc_tplg_enum_control), 877 count, size, "enums")) { 878 879 dev_err(tplg->dev, "ASoC: invalid count %d for enum controls\n", 880 count); 881 return -EINVAL; 882 } 883 884 for (i = 0; i < count; i++) { 885 ec = (struct snd_soc_tplg_enum_control *)tplg->pos; 886 tplg->pos += (sizeof(struct snd_soc_tplg_enum_control) + 887 ec->priv.size); 888 889 /* validate kcontrol */ 890 if (strnlen(ec->hdr.name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == 891 SNDRV_CTL_ELEM_ID_NAME_MAXLEN) 892 return -EINVAL; 893 894 se = kzalloc((sizeof(*se)), GFP_KERNEL); 895 if (se == NULL) 896 return -ENOMEM; 897 898 dev_dbg(tplg->dev, "ASoC: adding enum kcontrol %s size %d\n", 899 ec->hdr.name, ec->items); 900 901 memset(&kc, 0, sizeof(kc)); 902 kc.name = ec->hdr.name; 903 kc.private_value = (long)se; 904 kc.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 905 kc.access = ec->hdr.access; 906 907 se->reg = tplc_chan_get_reg(tplg, ec->channel, SNDRV_CHMAP_FL); 908 se->shift_l = tplc_chan_get_shift(tplg, ec->channel, 909 SNDRV_CHMAP_FL); 910 se->shift_r = tplc_chan_get_shift(tplg, ec->channel, 911 SNDRV_CHMAP_FL); 912 913 se->items = ec->items; 914 se->mask = ec->mask; 915 se->dobj.index = tplg->index; 916 se->dobj.type = SND_SOC_DOBJ_ENUM; 917 se->dobj.ops = tplg->ops; 918 INIT_LIST_HEAD(&se->dobj.list); 919 920 switch (ec->hdr.ops.info) { 921 case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE: 922 case SND_SOC_TPLG_CTL_ENUM_VALUE: 923 err = soc_tplg_denum_create_values(se, ec); 924 if (err < 0) { 925 dev_err(tplg->dev, 926 "ASoC: could not create values for %s\n", 927 ec->hdr.name); 928 kfree(se); 929 continue; 930 } 931 /* fall through and create texts */ 932 case SND_SOC_TPLG_CTL_ENUM: 933 case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE: 934 case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT: 935 err = soc_tplg_denum_create_texts(se, ec); 936 if (err < 0) { 937 dev_err(tplg->dev, 938 "ASoC: could not create texts for %s\n", 939 ec->hdr.name); 940 kfree(se); 941 continue; 942 } 943 break; 944 default: 945 dev_err(tplg->dev, 946 "ASoC: invalid enum control type %d for %s\n", 947 ec->hdr.ops.info, ec->hdr.name); 948 kfree(se); 949 continue; 950 } 951 952 /* map io handlers */ 953 err = soc_tplg_kcontrol_bind_io(&ec->hdr, &kc, io_ops, 954 ARRAY_SIZE(io_ops), tplg->io_ops, tplg->io_ops_count); 955 if (err) { 956 soc_control_err(tplg, &ec->hdr, ec->hdr.name); 957 kfree(se); 958 continue; 959 } 960 961 /* pass control to driver for optional further init */ 962 err = soc_tplg_init_kcontrol(tplg, &kc, 963 (struct snd_soc_tplg_ctl_hdr *) ec); 964 if (err < 0) { 965 dev_err(tplg->dev, "ASoC: failed to init %s\n", 966 ec->hdr.name); 967 kfree(se); 968 continue; 969 } 970 971 /* register control here */ 972 ret = soc_tplg_add_kcontrol(tplg, 973 &kc, &se->dobj.control.kcontrol); 974 if (ret < 0) { 975 dev_err(tplg->dev, "ASoC: could not add kcontrol %s\n", 976 ec->hdr.name); 977 kfree(se); 978 continue; 979 } 980 981 list_add(&se->dobj.list, &tplg->comp->dobj_list); 982 } 983 984 return 0; 985 } 986 987 static int soc_tplg_kcontrol_elems_load(struct soc_tplg *tplg, 988 struct snd_soc_tplg_hdr *hdr) 989 { 990 struct snd_soc_tplg_ctl_hdr *control_hdr; 991 int i; 992 993 if (tplg->pass != SOC_TPLG_PASS_MIXER) { 994 tplg->pos += hdr->size + hdr->payload_size; 995 return 0; 996 } 997 998 dev_dbg(tplg->dev, "ASoC: adding %d kcontrols at 0x%lx\n", hdr->count, 999 soc_tplg_get_offset(tplg)); 1000 1001 for (i = 0; i < hdr->count; i++) { 1002 1003 control_hdr = (struct snd_soc_tplg_ctl_hdr *)tplg->pos; 1004 1005 switch (control_hdr->ops.info) { 1006 case SND_SOC_TPLG_CTL_VOLSW: 1007 case SND_SOC_TPLG_CTL_STROBE: 1008 case SND_SOC_TPLG_CTL_VOLSW_SX: 1009 case SND_SOC_TPLG_CTL_VOLSW_XR_SX: 1010 case SND_SOC_TPLG_CTL_RANGE: 1011 case SND_SOC_TPLG_DAPM_CTL_VOLSW: 1012 case SND_SOC_TPLG_DAPM_CTL_PIN: 1013 soc_tplg_dmixer_create(tplg, 1, hdr->payload_size); 1014 break; 1015 case SND_SOC_TPLG_CTL_ENUM: 1016 case SND_SOC_TPLG_CTL_ENUM_VALUE: 1017 case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE: 1018 case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT: 1019 case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE: 1020 soc_tplg_denum_create(tplg, 1, hdr->payload_size); 1021 break; 1022 case SND_SOC_TPLG_CTL_BYTES: 1023 soc_tplg_dbytes_create(tplg, 1, hdr->payload_size); 1024 break; 1025 default: 1026 soc_bind_err(tplg, control_hdr, i); 1027 return -EINVAL; 1028 } 1029 } 1030 1031 return 0; 1032 } 1033 1034 static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg, 1035 struct snd_soc_tplg_hdr *hdr) 1036 { 1037 struct snd_soc_dapm_context *dapm = &tplg->comp->dapm; 1038 struct snd_soc_dapm_route route; 1039 struct snd_soc_tplg_dapm_graph_elem *elem; 1040 int count = hdr->count, i; 1041 1042 if (tplg->pass != SOC_TPLG_PASS_GRAPH) { 1043 tplg->pos += hdr->size + hdr->payload_size; 1044 return 0; 1045 } 1046 1047 if (soc_tplg_check_elem_count(tplg, 1048 sizeof(struct snd_soc_tplg_dapm_graph_elem), 1049 count, hdr->payload_size, "graph")) { 1050 1051 dev_err(tplg->dev, "ASoC: invalid count %d for DAPM routes\n", 1052 count); 1053 return -EINVAL; 1054 } 1055 1056 dev_dbg(tplg->dev, "ASoC: adding %d DAPM routes\n", count); 1057 1058 for (i = 0; i < count; i++) { 1059 elem = (struct snd_soc_tplg_dapm_graph_elem *)tplg->pos; 1060 tplg->pos += sizeof(struct snd_soc_tplg_dapm_graph_elem); 1061 1062 /* validate routes */ 1063 if (strnlen(elem->source, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == 1064 SNDRV_CTL_ELEM_ID_NAME_MAXLEN) 1065 return -EINVAL; 1066 if (strnlen(elem->sink, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == 1067 SNDRV_CTL_ELEM_ID_NAME_MAXLEN) 1068 return -EINVAL; 1069 if (strnlen(elem->control, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == 1070 SNDRV_CTL_ELEM_ID_NAME_MAXLEN) 1071 return -EINVAL; 1072 1073 route.source = elem->source; 1074 route.sink = elem->sink; 1075 route.connected = NULL; /* set to NULL atm for tplg users */ 1076 if (strnlen(elem->control, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == 0) 1077 route.control = NULL; 1078 else 1079 route.control = elem->control; 1080 1081 /* add route, but keep going if some fail */ 1082 snd_soc_dapm_add_routes(dapm, &route, 1); 1083 } 1084 1085 return 0; 1086 } 1087 1088 static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create( 1089 struct soc_tplg *tplg, int num_kcontrols) 1090 { 1091 struct snd_kcontrol_new *kc; 1092 struct soc_mixer_control *sm; 1093 struct snd_soc_tplg_mixer_control *mc; 1094 int i, err; 1095 1096 kc = kzalloc(sizeof(*kc) * num_kcontrols, GFP_KERNEL); 1097 if (kc == NULL) 1098 return NULL; 1099 1100 for (i = 0; i < num_kcontrols; i++) { 1101 mc = (struct snd_soc_tplg_mixer_control *)tplg->pos; 1102 sm = kzalloc(sizeof(*sm), GFP_KERNEL); 1103 if (sm == NULL) 1104 goto err; 1105 1106 tplg->pos += (sizeof(struct snd_soc_tplg_mixer_control) + 1107 mc->priv.size); 1108 1109 /* validate kcontrol */ 1110 if (strnlen(mc->hdr.name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == 1111 SNDRV_CTL_ELEM_ID_NAME_MAXLEN) 1112 goto err_str; 1113 1114 dev_dbg(tplg->dev, " adding DAPM widget mixer control %s at %d\n", 1115 mc->hdr.name, i); 1116 1117 kc[i].name = mc->hdr.name; 1118 kc[i].private_value = (long)sm; 1119 kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER; 1120 kc[i].access = mc->hdr.access; 1121 1122 /* we only support FL/FR channel mapping atm */ 1123 sm->reg = tplc_chan_get_reg(tplg, mc->channel, 1124 SNDRV_CHMAP_FL); 1125 sm->rreg = tplc_chan_get_reg(tplg, mc->channel, 1126 SNDRV_CHMAP_FR); 1127 sm->shift = tplc_chan_get_shift(tplg, mc->channel, 1128 SNDRV_CHMAP_FL); 1129 sm->rshift = tplc_chan_get_shift(tplg, mc->channel, 1130 SNDRV_CHMAP_FR); 1131 1132 sm->max = mc->max; 1133 sm->min = mc->min; 1134 sm->invert = mc->invert; 1135 sm->platform_max = mc->platform_max; 1136 sm->dobj.index = tplg->index; 1137 INIT_LIST_HEAD(&sm->dobj.list); 1138 1139 /* map io handlers */ 1140 err = soc_tplg_kcontrol_bind_io(&mc->hdr, &kc[i], io_ops, 1141 ARRAY_SIZE(io_ops), tplg->io_ops, tplg->io_ops_count); 1142 if (err) { 1143 soc_control_err(tplg, &mc->hdr, mc->hdr.name); 1144 kfree(sm); 1145 continue; 1146 } 1147 1148 /* pass control to driver for optional further init */ 1149 err = soc_tplg_init_kcontrol(tplg, &kc[i], 1150 (struct snd_soc_tplg_ctl_hdr *)mc); 1151 if (err < 0) { 1152 dev_err(tplg->dev, "ASoC: failed to init %s\n", 1153 mc->hdr.name); 1154 kfree(sm); 1155 continue; 1156 } 1157 } 1158 return kc; 1159 1160 err_str: 1161 kfree(sm); 1162 err: 1163 for (--i; i >= 0; i--) 1164 kfree((void *)kc[i].private_value); 1165 kfree(kc); 1166 return NULL; 1167 } 1168 1169 static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create( 1170 struct soc_tplg *tplg) 1171 { 1172 struct snd_kcontrol_new *kc; 1173 struct snd_soc_tplg_enum_control *ec; 1174 struct soc_enum *se; 1175 int i, err; 1176 1177 ec = (struct snd_soc_tplg_enum_control *)tplg->pos; 1178 tplg->pos += (sizeof(struct snd_soc_tplg_enum_control) + 1179 ec->priv.size); 1180 1181 /* validate kcontrol */ 1182 if (strnlen(ec->hdr.name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == 1183 SNDRV_CTL_ELEM_ID_NAME_MAXLEN) 1184 return NULL; 1185 1186 kc = kzalloc(sizeof(*kc), GFP_KERNEL); 1187 if (kc == NULL) 1188 return NULL; 1189 1190 se = kzalloc(sizeof(*se), GFP_KERNEL); 1191 if (se == NULL) 1192 goto err; 1193 1194 dev_dbg(tplg->dev, " adding DAPM widget enum control %s\n", 1195 ec->hdr.name); 1196 1197 kc->name = ec->hdr.name; 1198 kc->private_value = (long)se; 1199 kc->iface = SNDRV_CTL_ELEM_IFACE_MIXER; 1200 kc->access = ec->hdr.access; 1201 1202 /* we only support FL/FR channel mapping atm */ 1203 se->reg = tplc_chan_get_reg(tplg, ec->channel, SNDRV_CHMAP_FL); 1204 se->shift_l = tplc_chan_get_shift(tplg, ec->channel, SNDRV_CHMAP_FL); 1205 se->shift_r = tplc_chan_get_shift(tplg, ec->channel, SNDRV_CHMAP_FR); 1206 1207 se->items = ec->items; 1208 se->mask = ec->mask; 1209 se->dobj.index = tplg->index; 1210 1211 switch (ec->hdr.ops.info) { 1212 case SND_SOC_TPLG_CTL_ENUM_VALUE: 1213 case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE: 1214 err = soc_tplg_denum_create_values(se, ec); 1215 if (err < 0) { 1216 dev_err(tplg->dev, "ASoC: could not create values for %s\n", 1217 ec->hdr.name); 1218 goto err_se; 1219 } 1220 /* fall through to create texts */ 1221 case SND_SOC_TPLG_CTL_ENUM: 1222 case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE: 1223 case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT: 1224 err = soc_tplg_denum_create_texts(se, ec); 1225 if (err < 0) { 1226 dev_err(tplg->dev, "ASoC: could not create texts for %s\n", 1227 ec->hdr.name); 1228 goto err_se; 1229 } 1230 break; 1231 default: 1232 dev_err(tplg->dev, "ASoC: invalid enum control type %d for %s\n", 1233 ec->hdr.ops.info, ec->hdr.name); 1234 goto err_se; 1235 } 1236 1237 /* map io handlers */ 1238 err = soc_tplg_kcontrol_bind_io(&ec->hdr, kc, io_ops, 1239 ARRAY_SIZE(io_ops), tplg->io_ops, tplg->io_ops_count); 1240 if (err) { 1241 soc_control_err(tplg, &ec->hdr, ec->hdr.name); 1242 goto err_se; 1243 } 1244 1245 /* pass control to driver for optional further init */ 1246 err = soc_tplg_init_kcontrol(tplg, kc, 1247 (struct snd_soc_tplg_ctl_hdr *)ec); 1248 if (err < 0) { 1249 dev_err(tplg->dev, "ASoC: failed to init %s\n", 1250 ec->hdr.name); 1251 goto err_se; 1252 } 1253 1254 return kc; 1255 1256 err_se: 1257 /* free values and texts */ 1258 kfree(se->dobj.control.dvalues); 1259 for (i = 0; i < ec->items; i++) 1260 kfree(se->dobj.control.dtexts[i]); 1261 1262 kfree(se); 1263 err: 1264 kfree(kc); 1265 1266 return NULL; 1267 } 1268 1269 static struct snd_kcontrol_new *soc_tplg_dapm_widget_dbytes_create( 1270 struct soc_tplg *tplg, int count) 1271 { 1272 struct snd_soc_tplg_bytes_control *be; 1273 struct soc_bytes_ext *sbe; 1274 struct snd_kcontrol_new *kc; 1275 int i, err; 1276 1277 kc = kzalloc(sizeof(*kc) * count, GFP_KERNEL); 1278 if (!kc) 1279 return NULL; 1280 1281 for (i = 0; i < count; i++) { 1282 be = (struct snd_soc_tplg_bytes_control *)tplg->pos; 1283 1284 /* validate kcontrol */ 1285 if (strnlen(be->hdr.name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == 1286 SNDRV_CTL_ELEM_ID_NAME_MAXLEN) 1287 goto err; 1288 1289 sbe = kzalloc(sizeof(*sbe), GFP_KERNEL); 1290 if (sbe == NULL) 1291 goto err; 1292 1293 tplg->pos += (sizeof(struct snd_soc_tplg_bytes_control) + 1294 be->priv.size); 1295 1296 dev_dbg(tplg->dev, 1297 "ASoC: adding bytes kcontrol %s with access 0x%x\n", 1298 be->hdr.name, be->hdr.access); 1299 1300 memset(kc, 0, sizeof(*kc)); 1301 kc[i].name = be->hdr.name; 1302 kc[i].private_value = (long)sbe; 1303 kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER; 1304 kc[i].access = be->hdr.access; 1305 1306 sbe->max = be->max; 1307 INIT_LIST_HEAD(&sbe->dobj.list); 1308 1309 /* map standard io handlers and check for external handlers */ 1310 err = soc_tplg_kcontrol_bind_io(&be->hdr, &kc[i], io_ops, 1311 ARRAY_SIZE(io_ops), tplg->io_ops, 1312 tplg->io_ops_count); 1313 if (err) { 1314 soc_control_err(tplg, &be->hdr, be->hdr.name); 1315 kfree(sbe); 1316 continue; 1317 } 1318 1319 /* pass control to driver for optional further init */ 1320 err = soc_tplg_init_kcontrol(tplg, &kc[i], 1321 (struct snd_soc_tplg_ctl_hdr *)be); 1322 if (err < 0) { 1323 dev_err(tplg->dev, "ASoC: failed to init %s\n", 1324 be->hdr.name); 1325 kfree(sbe); 1326 continue; 1327 } 1328 } 1329 1330 return kc; 1331 1332 err: 1333 for (--i; i >= 0; i--) 1334 kfree((void *)kc[i].private_value); 1335 1336 kfree(kc); 1337 return NULL; 1338 } 1339 1340 static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg, 1341 struct snd_soc_tplg_dapm_widget *w) 1342 { 1343 struct snd_soc_dapm_context *dapm = &tplg->comp->dapm; 1344 struct snd_soc_dapm_widget template, *widget; 1345 struct snd_soc_tplg_ctl_hdr *control_hdr; 1346 struct snd_soc_card *card = tplg->comp->card; 1347 int ret = 0; 1348 1349 if (strnlen(w->name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == 1350 SNDRV_CTL_ELEM_ID_NAME_MAXLEN) 1351 return -EINVAL; 1352 if (strnlen(w->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == 1353 SNDRV_CTL_ELEM_ID_NAME_MAXLEN) 1354 return -EINVAL; 1355 1356 dev_dbg(tplg->dev, "ASoC: creating DAPM widget %s id %d\n", 1357 w->name, w->id); 1358 1359 memset(&template, 0, sizeof(template)); 1360 1361 /* map user to kernel widget ID */ 1362 template.id = get_widget_id(w->id); 1363 if (template.id < 0) 1364 return template.id; 1365 1366 template.name = kstrdup(w->name, GFP_KERNEL); 1367 if (!template.name) 1368 return -ENOMEM; 1369 template.sname = kstrdup(w->sname, GFP_KERNEL); 1370 if (!template.sname) { 1371 ret = -ENOMEM; 1372 goto err; 1373 } 1374 template.reg = w->reg; 1375 template.shift = w->shift; 1376 template.mask = w->mask; 1377 template.subseq = w->subseq; 1378 template.on_val = w->invert ? 0 : 1; 1379 template.off_val = w->invert ? 1 : 0; 1380 template.ignore_suspend = w->ignore_suspend; 1381 template.event_flags = w->event_flags; 1382 template.dobj.index = tplg->index; 1383 1384 tplg->pos += 1385 (sizeof(struct snd_soc_tplg_dapm_widget) + w->priv.size); 1386 if (w->num_kcontrols == 0) { 1387 template.num_kcontrols = 0; 1388 goto widget; 1389 } 1390 1391 control_hdr = (struct snd_soc_tplg_ctl_hdr *)tplg->pos; 1392 dev_dbg(tplg->dev, "ASoC: template %s has %d controls of type %x\n", 1393 w->name, w->num_kcontrols, control_hdr->type); 1394 1395 switch (control_hdr->ops.info) { 1396 case SND_SOC_TPLG_CTL_VOLSW: 1397 case SND_SOC_TPLG_CTL_STROBE: 1398 case SND_SOC_TPLG_CTL_VOLSW_SX: 1399 case SND_SOC_TPLG_CTL_VOLSW_XR_SX: 1400 case SND_SOC_TPLG_CTL_RANGE: 1401 case SND_SOC_TPLG_DAPM_CTL_VOLSW: 1402 template.num_kcontrols = w->num_kcontrols; 1403 template.kcontrol_news = 1404 soc_tplg_dapm_widget_dmixer_create(tplg, 1405 template.num_kcontrols); 1406 if (!template.kcontrol_news) { 1407 ret = -ENOMEM; 1408 goto hdr_err; 1409 } 1410 break; 1411 case SND_SOC_TPLG_CTL_ENUM: 1412 case SND_SOC_TPLG_CTL_ENUM_VALUE: 1413 case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE: 1414 case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT: 1415 case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE: 1416 template.dobj.widget.kcontrol_enum = 1; 1417 template.num_kcontrols = 1; 1418 template.kcontrol_news = 1419 soc_tplg_dapm_widget_denum_create(tplg); 1420 if (!template.kcontrol_news) { 1421 ret = -ENOMEM; 1422 goto hdr_err; 1423 } 1424 break; 1425 case SND_SOC_TPLG_CTL_BYTES: 1426 template.num_kcontrols = w->num_kcontrols; 1427 template.kcontrol_news = 1428 soc_tplg_dapm_widget_dbytes_create(tplg, 1429 template.num_kcontrols); 1430 if (!template.kcontrol_news) { 1431 ret = -ENOMEM; 1432 goto hdr_err; 1433 } 1434 break; 1435 default: 1436 dev_err(tplg->dev, "ASoC: invalid widget control type %d:%d:%d\n", 1437 control_hdr->ops.get, control_hdr->ops.put, 1438 control_hdr->ops.info); 1439 ret = -EINVAL; 1440 goto hdr_err; 1441 } 1442 1443 widget: 1444 ret = soc_tplg_widget_load(tplg, &template, w); 1445 if (ret < 0) 1446 goto hdr_err; 1447 1448 /* card dapm mutex is held by the core if we are loading topology 1449 * data during sound card init. */ 1450 if (card->instantiated) 1451 widget = snd_soc_dapm_new_control(dapm, &template); 1452 else 1453 widget = snd_soc_dapm_new_control_unlocked(dapm, &template); 1454 if (widget == NULL) { 1455 dev_err(tplg->dev, "ASoC: failed to create widget %s controls\n", 1456 w->name); 1457 goto hdr_err; 1458 } 1459 1460 widget->dobj.type = SND_SOC_DOBJ_WIDGET; 1461 widget->dobj.ops = tplg->ops; 1462 widget->dobj.index = tplg->index; 1463 list_add(&widget->dobj.list, &tplg->comp->dobj_list); 1464 return 0; 1465 1466 hdr_err: 1467 kfree(template.sname); 1468 err: 1469 kfree(template.name); 1470 return ret; 1471 } 1472 1473 static int soc_tplg_dapm_widget_elems_load(struct soc_tplg *tplg, 1474 struct snd_soc_tplg_hdr *hdr) 1475 { 1476 struct snd_soc_tplg_dapm_widget *widget; 1477 int ret, count = hdr->count, i; 1478 1479 if (tplg->pass != SOC_TPLG_PASS_WIDGET) 1480 return 0; 1481 1482 dev_dbg(tplg->dev, "ASoC: adding %d DAPM widgets\n", count); 1483 1484 for (i = 0; i < count; i++) { 1485 widget = (struct snd_soc_tplg_dapm_widget *) tplg->pos; 1486 ret = soc_tplg_dapm_widget_create(tplg, widget); 1487 if (ret < 0) 1488 dev_err(tplg->dev, "ASoC: failed to load widget %s\n", 1489 widget->name); 1490 } 1491 1492 return 0; 1493 } 1494 1495 static int soc_tplg_dapm_complete(struct soc_tplg *tplg) 1496 { 1497 struct snd_soc_card *card = tplg->comp->card; 1498 int ret; 1499 1500 /* Card might not have been registered at this point. 1501 * If so, just return success. 1502 */ 1503 if (!card || !card->instantiated) { 1504 dev_warn(tplg->dev, "ASoC: Parent card not yet available," 1505 "Do not add new widgets now\n"); 1506 return 0; 1507 } 1508 1509 ret = snd_soc_dapm_new_widgets(card); 1510 if (ret < 0) 1511 dev_err(tplg->dev, "ASoC: failed to create new widgets %d\n", 1512 ret); 1513 1514 return 0; 1515 } 1516 1517 static int soc_tplg_pcm_dai_elems_load(struct soc_tplg *tplg, 1518 struct snd_soc_tplg_hdr *hdr) 1519 { 1520 struct snd_soc_tplg_pcm_dai *pcm_dai; 1521 struct snd_soc_dobj *dobj; 1522 int count = hdr->count; 1523 int ret; 1524 1525 if (tplg->pass != SOC_TPLG_PASS_PCM_DAI) 1526 return 0; 1527 1528 pcm_dai = (struct snd_soc_tplg_pcm_dai *)tplg->pos; 1529 1530 if (soc_tplg_check_elem_count(tplg, 1531 sizeof(struct snd_soc_tplg_pcm_dai), count, 1532 hdr->payload_size, "PCM DAI")) { 1533 dev_err(tplg->dev, "ASoC: invalid count %d for PCM DAI elems\n", 1534 count); 1535 return -EINVAL; 1536 } 1537 1538 dev_dbg(tplg->dev, "ASoC: adding %d PCM DAIs\n", count); 1539 tplg->pos += sizeof(struct snd_soc_tplg_pcm_dai) * count; 1540 1541 dobj = kzalloc(sizeof(struct snd_soc_dobj), GFP_KERNEL); 1542 if (dobj == NULL) 1543 return -ENOMEM; 1544 1545 /* Call the platform driver call back to register the dais */ 1546 ret = soc_tplg_pcm_dai_load(tplg, pcm_dai, count); 1547 if (ret < 0) { 1548 dev_err(tplg->comp->dev, "ASoC: PCM DAI loading failed\n"); 1549 goto err; 1550 } 1551 1552 dobj->type = get_dobj_type(hdr, NULL); 1553 dobj->pcm_dai.count = count; 1554 dobj->pcm_dai.pd = pcm_dai; 1555 dobj->ops = tplg->ops; 1556 dobj->index = tplg->index; 1557 list_add(&dobj->list, &tplg->comp->dobj_list); 1558 return 0; 1559 1560 err: 1561 kfree(dobj); 1562 return ret; 1563 } 1564 1565 static int soc_tplg_manifest_load(struct soc_tplg *tplg, 1566 struct snd_soc_tplg_hdr *hdr) 1567 { 1568 struct snd_soc_tplg_manifest *manifest; 1569 1570 if (tplg->pass != SOC_TPLG_PASS_MANIFEST) 1571 return 0; 1572 1573 manifest = (struct snd_soc_tplg_manifest *)tplg->pos; 1574 tplg->pos += sizeof(struct snd_soc_tplg_manifest); 1575 1576 if (tplg->comp && tplg->ops && tplg->ops->manifest) 1577 return tplg->ops->manifest(tplg->comp, manifest); 1578 1579 dev_err(tplg->dev, "ASoC: Firmware manifest not supported\n"); 1580 return 0; 1581 } 1582 1583 /* validate header magic, size and type */ 1584 static int soc_valid_header(struct soc_tplg *tplg, 1585 struct snd_soc_tplg_hdr *hdr) 1586 { 1587 if (soc_tplg_get_hdr_offset(tplg) >= tplg->fw->size) 1588 return 0; 1589 1590 /* big endian firmware objects not supported atm */ 1591 if (hdr->magic == cpu_to_be32(SND_SOC_TPLG_MAGIC)) { 1592 dev_err(tplg->dev, 1593 "ASoC: pass %d big endian not supported header got %x at offset 0x%lx size 0x%zx.\n", 1594 tplg->pass, hdr->magic, 1595 soc_tplg_get_hdr_offset(tplg), tplg->fw->size); 1596 return -EINVAL; 1597 } 1598 1599 if (hdr->magic != SND_SOC_TPLG_MAGIC) { 1600 dev_err(tplg->dev, 1601 "ASoC: pass %d does not have a valid header got %x at offset 0x%lx size 0x%zx.\n", 1602 tplg->pass, hdr->magic, 1603 soc_tplg_get_hdr_offset(tplg), tplg->fw->size); 1604 return -EINVAL; 1605 } 1606 1607 if (hdr->abi != SND_SOC_TPLG_ABI_VERSION) { 1608 dev_err(tplg->dev, 1609 "ASoC: pass %d invalid ABI version got 0x%x need 0x%x at offset 0x%lx size 0x%zx.\n", 1610 tplg->pass, hdr->abi, 1611 SND_SOC_TPLG_ABI_VERSION, soc_tplg_get_hdr_offset(tplg), 1612 tplg->fw->size); 1613 return -EINVAL; 1614 } 1615 1616 if (hdr->payload_size == 0) { 1617 dev_err(tplg->dev, "ASoC: header has 0 size at offset 0x%lx.\n", 1618 soc_tplg_get_hdr_offset(tplg)); 1619 return -EINVAL; 1620 } 1621 1622 if (tplg->pass == hdr->type) 1623 dev_dbg(tplg->dev, 1624 "ASoC: Got 0x%x bytes of type %d version %d vendor %d at pass %d\n", 1625 hdr->payload_size, hdr->type, hdr->version, 1626 hdr->vendor_type, tplg->pass); 1627 1628 return 1; 1629 } 1630 1631 /* check header type and call appropriate handler */ 1632 static int soc_tplg_load_header(struct soc_tplg *tplg, 1633 struct snd_soc_tplg_hdr *hdr) 1634 { 1635 tplg->pos = tplg->hdr_pos + sizeof(struct snd_soc_tplg_hdr); 1636 1637 /* check for matching ID */ 1638 if (hdr->index != tplg->req_index && 1639 hdr->index != SND_SOC_TPLG_INDEX_ALL) 1640 return 0; 1641 1642 tplg->index = hdr->index; 1643 1644 switch (hdr->type) { 1645 case SND_SOC_TPLG_TYPE_MIXER: 1646 case SND_SOC_TPLG_TYPE_ENUM: 1647 case SND_SOC_TPLG_TYPE_BYTES: 1648 return soc_tplg_kcontrol_elems_load(tplg, hdr); 1649 case SND_SOC_TPLG_TYPE_DAPM_GRAPH: 1650 return soc_tplg_dapm_graph_elems_load(tplg, hdr); 1651 case SND_SOC_TPLG_TYPE_DAPM_WIDGET: 1652 return soc_tplg_dapm_widget_elems_load(tplg, hdr); 1653 case SND_SOC_TPLG_TYPE_PCM: 1654 case SND_SOC_TPLG_TYPE_DAI_LINK: 1655 case SND_SOC_TPLG_TYPE_CODEC_LINK: 1656 return soc_tplg_pcm_dai_elems_load(tplg, hdr); 1657 case SND_SOC_TPLG_TYPE_MANIFEST: 1658 return soc_tplg_manifest_load(tplg, hdr); 1659 default: 1660 /* bespoke vendor data object */ 1661 return soc_tplg_vendor_load(tplg, hdr); 1662 } 1663 1664 return 0; 1665 } 1666 1667 /* process the topology file headers */ 1668 static int soc_tplg_process_headers(struct soc_tplg *tplg) 1669 { 1670 struct snd_soc_tplg_hdr *hdr; 1671 int ret; 1672 1673 tplg->pass = SOC_TPLG_PASS_START; 1674 1675 /* process the header types from start to end */ 1676 while (tplg->pass <= SOC_TPLG_PASS_END) { 1677 1678 tplg->hdr_pos = tplg->fw->data; 1679 hdr = (struct snd_soc_tplg_hdr *)tplg->hdr_pos; 1680 1681 while (!soc_tplg_is_eof(tplg)) { 1682 1683 /* make sure header is valid before loading */ 1684 ret = soc_valid_header(tplg, hdr); 1685 if (ret < 0) 1686 return ret; 1687 else if (ret == 0) 1688 break; 1689 1690 /* load the header object */ 1691 ret = soc_tplg_load_header(tplg, hdr); 1692 if (ret < 0) 1693 return ret; 1694 1695 /* goto next header */ 1696 tplg->hdr_pos += hdr->payload_size + 1697 sizeof(struct snd_soc_tplg_hdr); 1698 hdr = (struct snd_soc_tplg_hdr *)tplg->hdr_pos; 1699 } 1700 1701 /* next data type pass */ 1702 tplg->pass++; 1703 } 1704 1705 /* signal DAPM we are complete */ 1706 ret = soc_tplg_dapm_complete(tplg); 1707 if (ret < 0) 1708 dev_err(tplg->dev, 1709 "ASoC: failed to initialise DAPM from Firmware\n"); 1710 1711 return ret; 1712 } 1713 1714 static int soc_tplg_load(struct soc_tplg *tplg) 1715 { 1716 int ret; 1717 1718 ret = soc_tplg_process_headers(tplg); 1719 if (ret == 0) 1720 soc_tplg_complete(tplg); 1721 1722 return ret; 1723 } 1724 1725 /* load audio component topology from "firmware" file */ 1726 int snd_soc_tplg_component_load(struct snd_soc_component *comp, 1727 struct snd_soc_tplg_ops *ops, const struct firmware *fw, u32 id) 1728 { 1729 struct soc_tplg tplg; 1730 1731 /* setup parsing context */ 1732 memset(&tplg, 0, sizeof(tplg)); 1733 tplg.fw = fw; 1734 tplg.dev = comp->dev; 1735 tplg.comp = comp; 1736 tplg.ops = ops; 1737 tplg.req_index = id; 1738 tplg.io_ops = ops->io_ops; 1739 tplg.io_ops_count = ops->io_ops_count; 1740 1741 return soc_tplg_load(&tplg); 1742 } 1743 EXPORT_SYMBOL_GPL(snd_soc_tplg_component_load); 1744 1745 /* remove this dynamic widget */ 1746 void snd_soc_tplg_widget_remove(struct snd_soc_dapm_widget *w) 1747 { 1748 /* make sure we are a widget */ 1749 if (w->dobj.type != SND_SOC_DOBJ_WIDGET) 1750 return; 1751 1752 remove_widget(w->dapm->component, &w->dobj, SOC_TPLG_PASS_WIDGET); 1753 } 1754 EXPORT_SYMBOL_GPL(snd_soc_tplg_widget_remove); 1755 1756 /* remove all dynamic widgets from this DAPM context */ 1757 void snd_soc_tplg_widget_remove_all(struct snd_soc_dapm_context *dapm, 1758 u32 index) 1759 { 1760 struct snd_soc_dapm_widget *w, *next_w; 1761 struct snd_soc_dapm_path *p, *next_p; 1762 1763 list_for_each_entry_safe(w, next_w, &dapm->card->widgets, list) { 1764 1765 /* make sure we are a widget with correct context */ 1766 if (w->dobj.type != SND_SOC_DOBJ_WIDGET || w->dapm != dapm) 1767 continue; 1768 1769 /* match ID */ 1770 if (w->dobj.index != index && 1771 w->dobj.index != SND_SOC_TPLG_INDEX_ALL) 1772 continue; 1773 1774 list_del(&w->list); 1775 1776 /* 1777 * remove source and sink paths associated to this widget. 1778 * While removing the path, remove reference to it from both 1779 * source and sink widgets so that path is removed only once. 1780 */ 1781 list_for_each_entry_safe(p, next_p, &w->sources, list_sink) { 1782 list_del(&p->list_sink); 1783 list_del(&p->list_source); 1784 list_del(&p->list); 1785 kfree(p); 1786 } 1787 list_for_each_entry_safe(p, next_p, &w->sinks, list_source) { 1788 list_del(&p->list_sink); 1789 list_del(&p->list_source); 1790 list_del(&p->list); 1791 kfree(p); 1792 } 1793 /* check and free and dynamic widget kcontrols */ 1794 snd_soc_tplg_widget_remove(w); 1795 kfree(w->kcontrols); 1796 kfree(w->name); 1797 kfree(w); 1798 } 1799 } 1800 EXPORT_SYMBOL_GPL(snd_soc_tplg_widget_remove_all); 1801 1802 /* remove dynamic controls from the component driver */ 1803 int snd_soc_tplg_component_remove(struct snd_soc_component *comp, u32 index) 1804 { 1805 struct snd_soc_dobj *dobj, *next_dobj; 1806 int pass = SOC_TPLG_PASS_END; 1807 1808 /* process the header types from end to start */ 1809 while (pass >= SOC_TPLG_PASS_START) { 1810 1811 /* remove mixer controls */ 1812 list_for_each_entry_safe(dobj, next_dobj, &comp->dobj_list, 1813 list) { 1814 1815 /* match index */ 1816 if (dobj->index != index && 1817 dobj->index != SND_SOC_TPLG_INDEX_ALL) 1818 continue; 1819 1820 switch (dobj->type) { 1821 case SND_SOC_DOBJ_MIXER: 1822 remove_mixer(comp, dobj, pass); 1823 break; 1824 case SND_SOC_DOBJ_ENUM: 1825 remove_enum(comp, dobj, pass); 1826 break; 1827 case SND_SOC_DOBJ_BYTES: 1828 remove_bytes(comp, dobj, pass); 1829 break; 1830 case SND_SOC_DOBJ_WIDGET: 1831 remove_widget(comp, dobj, pass); 1832 break; 1833 case SND_SOC_DOBJ_PCM: 1834 case SND_SOC_DOBJ_DAI_LINK: 1835 case SND_SOC_DOBJ_CODEC_LINK: 1836 remove_pcm_dai(comp, dobj, pass); 1837 break; 1838 default: 1839 dev_err(comp->dev, "ASoC: invalid component type %d for removal\n", 1840 dobj->type); 1841 break; 1842 } 1843 } 1844 pass--; 1845 } 1846 1847 /* let caller know if FW can be freed when no objects are left */ 1848 return !list_empty(&comp->dobj_list); 1849 } 1850 EXPORT_SYMBOL_GPL(snd_soc_tplg_component_remove); 1851