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