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