1/* 2 * soc-dapm.c -- ALSA SoC Dynamic Audio Power Management 3 * 4 * Copyright 2005 Wolfson Microelectronics PLC. 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk> 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation; either version 2 of the License, or (at your 10 * option) any later version. 11 * 12 * Features: 13 * o Changes power status of internal codec blocks depending on the 14 * dynamic configuration of codec internal audio paths and active 15 * DACs/ADCs. 16 * o Platform power domain - can support external components i.e. amps and 17 * mic/headphone insertion events. 18 * o Automatic Mic Bias support 19 * o Jack insertion power event initiation - e.g. hp insertion will enable 20 * sinks, dacs, etc 21 * o Delayed power down of audio subsystem to reduce pops between a quick 22 * device reopen. 23 * 24 */ 25 26#include <linux/module.h> 27#include <linux/moduleparam.h> 28#include <linux/init.h> 29#include <linux/async.h> 30#include <linux/delay.h> 31#include <linux/pm.h> 32#include <linux/bitops.h> 33#include <linux/platform_device.h> 34#include <linux/jiffies.h> 35#include <linux/debugfs.h> 36#include <linux/pm_runtime.h> 37#include <linux/regulator/consumer.h> 38#include <linux/clk.h> 39#include <linux/slab.h> 40#include <sound/core.h> 41#include <sound/pcm.h> 42#include <sound/pcm_params.h> 43#include <sound/soc.h> 44#include <sound/initval.h> 45 46#include <trace/events/asoc.h> 47 48#define DAPM_UPDATE_STAT(widget, val) widget->dapm->card->dapm_stats.val++; 49 50#define SND_SOC_DAPM_DIR_REVERSE(x) ((x == SND_SOC_DAPM_DIR_IN) ? \ 51 SND_SOC_DAPM_DIR_OUT : SND_SOC_DAPM_DIR_IN) 52 53#define snd_soc_dapm_for_each_direction(dir) \ 54 for ((dir) = SND_SOC_DAPM_DIR_IN; (dir) <= SND_SOC_DAPM_DIR_OUT; \ 55 (dir)++) 56 57static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm, 58 struct snd_soc_dapm_widget *wsource, struct snd_soc_dapm_widget *wsink, 59 const char *control, 60 int (*connected)(struct snd_soc_dapm_widget *source, 61 struct snd_soc_dapm_widget *sink)); 62 63struct snd_soc_dapm_widget * 64snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, 65 const struct snd_soc_dapm_widget *widget); 66 67struct snd_soc_dapm_widget * 68snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm, 69 const struct snd_soc_dapm_widget *widget); 70 71/* dapm power sequences - make this per codec in the future */ 72static int dapm_up_seq[] = { 73 [snd_soc_dapm_pre] = 0, 74 [snd_soc_dapm_regulator_supply] = 1, 75 [snd_soc_dapm_clock_supply] = 1, 76 [snd_soc_dapm_supply] = 2, 77 [snd_soc_dapm_micbias] = 3, 78 [snd_soc_dapm_dai_link] = 2, 79 [snd_soc_dapm_dai_in] = 4, 80 [snd_soc_dapm_dai_out] = 4, 81 [snd_soc_dapm_aif_in] = 4, 82 [snd_soc_dapm_aif_out] = 4, 83 [snd_soc_dapm_mic] = 5, 84 [snd_soc_dapm_mux] = 6, 85 [snd_soc_dapm_demux] = 6, 86 [snd_soc_dapm_dac] = 7, 87 [snd_soc_dapm_switch] = 8, 88 [snd_soc_dapm_mixer] = 8, 89 [snd_soc_dapm_mixer_named_ctl] = 8, 90 [snd_soc_dapm_pga] = 9, 91 [snd_soc_dapm_adc] = 10, 92 [snd_soc_dapm_out_drv] = 11, 93 [snd_soc_dapm_hp] = 11, 94 [snd_soc_dapm_spk] = 11, 95 [snd_soc_dapm_line] = 11, 96 [snd_soc_dapm_kcontrol] = 12, 97 [snd_soc_dapm_post] = 13, 98}; 99 100static int dapm_down_seq[] = { 101 [snd_soc_dapm_pre] = 0, 102 [snd_soc_dapm_kcontrol] = 1, 103 [snd_soc_dapm_adc] = 2, 104 [snd_soc_dapm_hp] = 3, 105 [snd_soc_dapm_spk] = 3, 106 [snd_soc_dapm_line] = 3, 107 [snd_soc_dapm_out_drv] = 3, 108 [snd_soc_dapm_pga] = 4, 109 [snd_soc_dapm_switch] = 5, 110 [snd_soc_dapm_mixer_named_ctl] = 5, 111 [snd_soc_dapm_mixer] = 5, 112 [snd_soc_dapm_dac] = 6, 113 [snd_soc_dapm_mic] = 7, 114 [snd_soc_dapm_micbias] = 8, 115 [snd_soc_dapm_mux] = 9, 116 [snd_soc_dapm_demux] = 9, 117 [snd_soc_dapm_aif_in] = 10, 118 [snd_soc_dapm_aif_out] = 10, 119 [snd_soc_dapm_dai_in] = 10, 120 [snd_soc_dapm_dai_out] = 10, 121 [snd_soc_dapm_dai_link] = 11, 122 [snd_soc_dapm_supply] = 12, 123 [snd_soc_dapm_clock_supply] = 13, 124 [snd_soc_dapm_regulator_supply] = 13, 125 [snd_soc_dapm_post] = 14, 126}; 127 128static void dapm_assert_locked(struct snd_soc_dapm_context *dapm) 129{ 130 if (dapm->card && dapm->card->instantiated) 131 lockdep_assert_held(&dapm->card->dapm_mutex); 132} 133 134static void pop_wait(u32 pop_time) 135{ 136 if (pop_time) 137 schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time)); 138} 139 140static void pop_dbg(struct device *dev, u32 pop_time, const char *fmt, ...) 141{ 142 va_list args; 143 char *buf; 144 145 if (!pop_time) 146 return; 147 148 buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 149 if (buf == NULL) 150 return; 151 152 va_start(args, fmt); 153 vsnprintf(buf, PAGE_SIZE, fmt, args); 154 dev_info(dev, "%s", buf); 155 va_end(args); 156 157 kfree(buf); 158} 159 160static bool dapm_dirty_widget(struct snd_soc_dapm_widget *w) 161{ 162 return !list_empty(&w->dirty); 163} 164 165static void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason) 166{ 167 dapm_assert_locked(w->dapm); 168 169 if (!dapm_dirty_widget(w)) { 170 dev_vdbg(w->dapm->dev, "Marking %s dirty due to %s\n", 171 w->name, reason); 172 list_add_tail(&w->dirty, &w->dapm->card->dapm_dirty); 173 } 174} 175 176/* 177 * Common implementation for dapm_widget_invalidate_input_paths() and 178 * dapm_widget_invalidate_output_paths(). The function is inlined since the 179 * combined size of the two specialized functions is only marginally larger then 180 * the size of the generic function and at the same time the fast path of the 181 * specialized functions is significantly smaller than the generic function. 182 */ 183static __always_inline void dapm_widget_invalidate_paths( 184 struct snd_soc_dapm_widget *w, enum snd_soc_dapm_direction dir) 185{ 186 enum snd_soc_dapm_direction rdir = SND_SOC_DAPM_DIR_REVERSE(dir); 187 struct snd_soc_dapm_widget *node; 188 struct snd_soc_dapm_path *p; 189 LIST_HEAD(list); 190 191 dapm_assert_locked(w->dapm); 192 193 if (w->endpoints[dir] == -1) 194 return; 195 196 list_add_tail(&w->work_list, &list); 197 w->endpoints[dir] = -1; 198 199 list_for_each_entry(w, &list, work_list) { 200 snd_soc_dapm_widget_for_each_path(w, dir, p) { 201 if (p->is_supply || p->weak || !p->connect) 202 continue; 203 node = p->node[rdir]; 204 if (node->endpoints[dir] != -1) { 205 node->endpoints[dir] = -1; 206 list_add_tail(&node->work_list, &list); 207 } 208 } 209 } 210} 211 212/* 213 * dapm_widget_invalidate_input_paths() - Invalidate the cached number of 214 * input paths 215 * @w: The widget for which to invalidate the cached number of input paths 216 * 217 * Resets the cached number of inputs for the specified widget and all widgets 218 * that can be reached via outcoming paths from the widget. 219 * 220 * This function must be called if the number of output paths for a widget might 221 * have changed. E.g. if the source state of a widget changes or a path is added 222 * or activated with the widget as the sink. 223 */ 224static void dapm_widget_invalidate_input_paths(struct snd_soc_dapm_widget *w) 225{ 226 dapm_widget_invalidate_paths(w, SND_SOC_DAPM_DIR_IN); 227} 228 229/* 230 * dapm_widget_invalidate_output_paths() - Invalidate the cached number of 231 * output paths 232 * @w: The widget for which to invalidate the cached number of output paths 233 * 234 * Resets the cached number of outputs for the specified widget and all widgets 235 * that can be reached via incoming paths from the widget. 236 * 237 * This function must be called if the number of output paths for a widget might 238 * have changed. E.g. if the sink state of a widget changes or a path is added 239 * or activated with the widget as the source. 240 */ 241static void dapm_widget_invalidate_output_paths(struct snd_soc_dapm_widget *w) 242{ 243 dapm_widget_invalidate_paths(w, SND_SOC_DAPM_DIR_OUT); 244} 245 246/* 247 * dapm_path_invalidate() - Invalidates the cached number of inputs and outputs 248 * for the widgets connected to a path 249 * @p: The path to invalidate 250 * 251 * Resets the cached number of inputs for the sink of the path and the cached 252 * number of outputs for the source of the path. 253 * 254 * This function must be called when a path is added, removed or the connected 255 * state changes. 256 */ 257static void dapm_path_invalidate(struct snd_soc_dapm_path *p) 258{ 259 /* 260 * Weak paths or supply paths do not influence the number of input or 261 * output paths of their neighbors. 262 */ 263 if (p->weak || p->is_supply) 264 return; 265 266 /* 267 * The number of connected endpoints is the sum of the number of 268 * connected endpoints of all neighbors. If a node with 0 connected 269 * endpoints is either connected or disconnected that sum won't change, 270 * so there is no need to re-check the path. 271 */ 272 if (p->source->endpoints[SND_SOC_DAPM_DIR_IN] != 0) 273 dapm_widget_invalidate_input_paths(p->sink); 274 if (p->sink->endpoints[SND_SOC_DAPM_DIR_OUT] != 0) 275 dapm_widget_invalidate_output_paths(p->source); 276} 277 278void dapm_mark_endpoints_dirty(struct snd_soc_card *card) 279{ 280 struct snd_soc_dapm_widget *w; 281 282 mutex_lock(&card->dapm_mutex); 283 284 list_for_each_entry(w, &card->widgets, list) { 285 if (w->is_ep) { 286 dapm_mark_dirty(w, "Rechecking endpoints"); 287 if (w->is_ep & SND_SOC_DAPM_EP_SINK) 288 dapm_widget_invalidate_output_paths(w); 289 if (w->is_ep & SND_SOC_DAPM_EP_SOURCE) 290 dapm_widget_invalidate_input_paths(w); 291 } 292 } 293 294 mutex_unlock(&card->dapm_mutex); 295} 296EXPORT_SYMBOL_GPL(dapm_mark_endpoints_dirty); 297 298/* create a new dapm widget */ 299static inline struct snd_soc_dapm_widget *dapm_cnew_widget( 300 const struct snd_soc_dapm_widget *_widget) 301{ 302 return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL); 303} 304 305struct dapm_kcontrol_data { 306 unsigned int value; 307 struct snd_soc_dapm_widget *widget; 308 struct list_head paths; 309 struct snd_soc_dapm_widget_list *wlist; 310}; 311 312static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget, 313 struct snd_kcontrol *kcontrol) 314{ 315 struct dapm_kcontrol_data *data; 316 struct soc_mixer_control *mc; 317 struct soc_enum *e; 318 const char *name; 319 int ret; 320 321 data = kzalloc(sizeof(*data), GFP_KERNEL); 322 if (!data) 323 return -ENOMEM; 324 325 INIT_LIST_HEAD(&data->paths); 326 327 switch (widget->id) { 328 case snd_soc_dapm_switch: 329 case snd_soc_dapm_mixer: 330 case snd_soc_dapm_mixer_named_ctl: 331 mc = (struct soc_mixer_control *)kcontrol->private_value; 332 333 if (mc->autodisable) { 334 struct snd_soc_dapm_widget template; 335 336 name = kasprintf(GFP_KERNEL, "%s %s", kcontrol->id.name, 337 "Autodisable"); 338 if (!name) { 339 ret = -ENOMEM; 340 goto err_data; 341 } 342 343 memset(&template, 0, sizeof(template)); 344 template.reg = mc->reg; 345 template.mask = (1 << fls(mc->max)) - 1; 346 template.shift = mc->shift; 347 if (mc->invert) 348 template.off_val = mc->max; 349 else 350 template.off_val = 0; 351 template.on_val = template.off_val; 352 template.id = snd_soc_dapm_kcontrol; 353 template.name = name; 354 355 data->value = template.on_val; 356 357 data->widget = 358 snd_soc_dapm_new_control_unlocked(widget->dapm, 359 &template); 360 kfree(name); 361 if (!data->widget) { 362 ret = -ENOMEM; 363 goto err_data; 364 } 365 } 366 break; 367 case snd_soc_dapm_demux: 368 case snd_soc_dapm_mux: 369 e = (struct soc_enum *)kcontrol->private_value; 370 371 if (e->autodisable) { 372 struct snd_soc_dapm_widget template; 373 374 name = kasprintf(GFP_KERNEL, "%s %s", kcontrol->id.name, 375 "Autodisable"); 376 if (!name) { 377 ret = -ENOMEM; 378 goto err_data; 379 } 380 381 memset(&template, 0, sizeof(template)); 382 template.reg = e->reg; 383 template.mask = e->mask << e->shift_l; 384 template.shift = e->shift_l; 385 template.off_val = snd_soc_enum_item_to_val(e, 0); 386 template.on_val = template.off_val; 387 template.id = snd_soc_dapm_kcontrol; 388 template.name = name; 389 390 data->value = template.on_val; 391 392 data->widget = snd_soc_dapm_new_control_unlocked( 393 widget->dapm, &template); 394 kfree(name); 395 if (!data->widget) { 396 ret = -ENOMEM; 397 goto err_data; 398 } 399 400 snd_soc_dapm_add_path(widget->dapm, data->widget, 401 widget, NULL, NULL); 402 } 403 break; 404 default: 405 break; 406 } 407 408 kcontrol->private_data = data; 409 410 return 0; 411 412err_data: 413 kfree(data); 414 return ret; 415} 416 417static void dapm_kcontrol_free(struct snd_kcontrol *kctl) 418{ 419 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kctl); 420 kfree(data->wlist); 421 kfree(data); 422} 423 424static struct snd_soc_dapm_widget_list *dapm_kcontrol_get_wlist( 425 const struct snd_kcontrol *kcontrol) 426{ 427 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol); 428 429 return data->wlist; 430} 431 432static int dapm_kcontrol_add_widget(struct snd_kcontrol *kcontrol, 433 struct snd_soc_dapm_widget *widget) 434{ 435 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol); 436 struct snd_soc_dapm_widget_list *new_wlist; 437 unsigned int n; 438 439 if (data->wlist) 440 n = data->wlist->num_widgets + 1; 441 else 442 n = 1; 443 444 new_wlist = krealloc(data->wlist, 445 sizeof(*new_wlist) + sizeof(widget) * n, GFP_KERNEL); 446 if (!new_wlist) 447 return -ENOMEM; 448 449 new_wlist->widgets[n - 1] = widget; 450 new_wlist->num_widgets = n; 451 452 data->wlist = new_wlist; 453 454 return 0; 455} 456 457static void dapm_kcontrol_add_path(const struct snd_kcontrol *kcontrol, 458 struct snd_soc_dapm_path *path) 459{ 460 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol); 461 462 list_add_tail(&path->list_kcontrol, &data->paths); 463} 464 465static bool dapm_kcontrol_is_powered(const struct snd_kcontrol *kcontrol) 466{ 467 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol); 468 469 if (!data->widget) 470 return true; 471 472 return data->widget->power; 473} 474 475static struct list_head *dapm_kcontrol_get_path_list( 476 const struct snd_kcontrol *kcontrol) 477{ 478 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol); 479 480 return &data->paths; 481} 482 483#define dapm_kcontrol_for_each_path(path, kcontrol) \ 484 list_for_each_entry(path, dapm_kcontrol_get_path_list(kcontrol), \ 485 list_kcontrol) 486 487unsigned int dapm_kcontrol_get_value(const struct snd_kcontrol *kcontrol) 488{ 489 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol); 490 491 return data->value; 492} 493EXPORT_SYMBOL_GPL(dapm_kcontrol_get_value); 494 495static bool dapm_kcontrol_set_value(const struct snd_kcontrol *kcontrol, 496 unsigned int value) 497{ 498 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol); 499 500 if (data->value == value) 501 return false; 502 503 if (data->widget) 504 data->widget->on_val = value; 505 506 data->value = value; 507 508 return true; 509} 510 511/** 512 * snd_soc_dapm_kcontrol_widget() - Returns the widget associated to a 513 * kcontrol 514 * @kcontrol: The kcontrol 515 */ 516struct snd_soc_dapm_widget *snd_soc_dapm_kcontrol_widget( 517 struct snd_kcontrol *kcontrol) 518{ 519 return dapm_kcontrol_get_wlist(kcontrol)->widgets[0]; 520} 521EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_widget); 522 523/** 524 * snd_soc_dapm_kcontrol_dapm() - Returns the dapm context associated to a 525 * kcontrol 526 * @kcontrol: The kcontrol 527 * 528 * Note: This function must only be used on kcontrols that are known to have 529 * been registered for a CODEC. Otherwise the behaviour is undefined. 530 */ 531struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm( 532 struct snd_kcontrol *kcontrol) 533{ 534 return dapm_kcontrol_get_wlist(kcontrol)->widgets[0]->dapm; 535} 536EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_dapm); 537 538static void dapm_reset(struct snd_soc_card *card) 539{ 540 struct snd_soc_dapm_widget *w; 541 542 lockdep_assert_held(&card->dapm_mutex); 543 544 memset(&card->dapm_stats, 0, sizeof(card->dapm_stats)); 545 546 list_for_each_entry(w, &card->widgets, list) { 547 w->new_power = w->power; 548 w->power_checked = false; 549 } 550} 551 552static const char *soc_dapm_prefix(struct snd_soc_dapm_context *dapm) 553{ 554 if (!dapm->component) 555 return NULL; 556 return dapm->component->name_prefix; 557} 558 559static int soc_dapm_read(struct snd_soc_dapm_context *dapm, int reg, 560 unsigned int *value) 561{ 562 if (!dapm->component) 563 return -EIO; 564 return snd_soc_component_read(dapm->component, reg, value); 565} 566 567static int soc_dapm_update_bits(struct snd_soc_dapm_context *dapm, 568 int reg, unsigned int mask, unsigned int value) 569{ 570 if (!dapm->component) 571 return -EIO; 572 return snd_soc_component_update_bits(dapm->component, reg, 573 mask, value); 574} 575 576static int soc_dapm_test_bits(struct snd_soc_dapm_context *dapm, 577 int reg, unsigned int mask, unsigned int value) 578{ 579 if (!dapm->component) 580 return -EIO; 581 return snd_soc_component_test_bits(dapm->component, reg, mask, value); 582} 583 584static void soc_dapm_async_complete(struct snd_soc_dapm_context *dapm) 585{ 586 if (dapm->component) 587 snd_soc_component_async_complete(dapm->component); 588} 589 590static struct snd_soc_dapm_widget * 591dapm_wcache_lookup(struct snd_soc_dapm_wcache *wcache, const char *name) 592{ 593 struct snd_soc_dapm_widget *w = wcache->widget; 594 struct list_head *wlist; 595 const int depth = 2; 596 int i = 0; 597 598 if (w) { 599 wlist = &w->dapm->card->widgets; 600 601 list_for_each_entry_from(w, wlist, list) { 602 if (!strcmp(name, w->name)) 603 return w; 604 605 if (++i == depth) 606 break; 607 } 608 } 609 610 return NULL; 611} 612 613static inline void dapm_wcache_update(struct snd_soc_dapm_wcache *wcache, 614 struct snd_soc_dapm_widget *w) 615{ 616 wcache->widget = w; 617} 618 619/** 620 * snd_soc_dapm_force_bias_level() - Sets the DAPM bias level 621 * @dapm: The DAPM context for which to set the level 622 * @level: The level to set 623 * 624 * Forces the DAPM bias level to a specific state. It will call the bias level 625 * callback of DAPM context with the specified level. This will even happen if 626 * the context is already at the same level. Furthermore it will not go through 627 * the normal bias level sequencing, meaning any intermediate states between the 628 * current and the target state will not be entered. 629 * 630 * Note that the change in bias level is only temporary and the next time 631 * snd_soc_dapm_sync() is called the state will be set to the level as 632 * determined by the DAPM core. The function is mainly intended to be used to 633 * used during probe or resume from suspend to power up the device so 634 * initialization can be done, before the DAPM core takes over. 635 */ 636int snd_soc_dapm_force_bias_level(struct snd_soc_dapm_context *dapm, 637 enum snd_soc_bias_level level) 638{ 639 int ret = 0; 640 641 if (dapm->set_bias_level) 642 ret = dapm->set_bias_level(dapm, level); 643 644 if (ret == 0) 645 dapm->bias_level = level; 646 647 return ret; 648} 649EXPORT_SYMBOL_GPL(snd_soc_dapm_force_bias_level); 650 651/** 652 * snd_soc_dapm_set_bias_level - set the bias level for the system 653 * @dapm: DAPM context 654 * @level: level to configure 655 * 656 * Configure the bias (power) levels for the SoC audio device. 657 * 658 * Returns 0 for success else error. 659 */ 660static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm, 661 enum snd_soc_bias_level level) 662{ 663 struct snd_soc_card *card = dapm->card; 664 int ret = 0; 665 666 trace_snd_soc_bias_level_start(card, level); 667 668 if (card && card->set_bias_level) 669 ret = card->set_bias_level(card, dapm, level); 670 if (ret != 0) 671 goto out; 672 673 if (!card || dapm != &card->dapm) 674 ret = snd_soc_dapm_force_bias_level(dapm, level); 675 676 if (ret != 0) 677 goto out; 678 679 if (card && card->set_bias_level_post) 680 ret = card->set_bias_level_post(card, dapm, level); 681out: 682 trace_snd_soc_bias_level_done(card, level); 683 684 return ret; 685} 686 687/* connect mux widget to its interconnecting audio paths */ 688static int dapm_connect_mux(struct snd_soc_dapm_context *dapm, 689 struct snd_soc_dapm_path *path, const char *control_name, 690 struct snd_soc_dapm_widget *w) 691{ 692 const struct snd_kcontrol_new *kcontrol = &w->kcontrol_news[0]; 693 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 694 unsigned int val, item; 695 int i; 696 697 if (e->reg != SND_SOC_NOPM) { 698 soc_dapm_read(dapm, e->reg, &val); 699 val = (val >> e->shift_l) & e->mask; 700 item = snd_soc_enum_val_to_item(e, val); 701 } else { 702 /* since a virtual mux has no backing registers to 703 * decide which path to connect, it will try to match 704 * with the first enumeration. This is to ensure 705 * that the default mux choice (the first) will be 706 * correctly powered up during initialization. 707 */ 708 item = 0; 709 } 710 711 for (i = 0; i < e->items; i++) { 712 if (!(strcmp(control_name, e->texts[i]))) { 713 path->name = e->texts[i]; 714 if (i == item) 715 path->connect = 1; 716 else 717 path->connect = 0; 718 return 0; 719 } 720 } 721 722 return -ENODEV; 723} 724 725/* set up initial codec paths */ 726static void dapm_set_mixer_path_status(struct snd_soc_dapm_path *p, int i) 727{ 728 struct soc_mixer_control *mc = (struct soc_mixer_control *) 729 p->sink->kcontrol_news[i].private_value; 730 unsigned int reg = mc->reg; 731 unsigned int shift = mc->shift; 732 unsigned int max = mc->max; 733 unsigned int mask = (1 << fls(max)) - 1; 734 unsigned int invert = mc->invert; 735 unsigned int val; 736 737 if (reg != SND_SOC_NOPM) { 738 soc_dapm_read(p->sink->dapm, reg, &val); 739 val = (val >> shift) & mask; 740 if (invert) 741 val = max - val; 742 p->connect = !!val; 743 } else { 744 p->connect = 0; 745 } 746} 747 748/* connect mixer widget to its interconnecting audio paths */ 749static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm, 750 struct snd_soc_dapm_path *path, const char *control_name) 751{ 752 int i; 753 754 /* search for mixer kcontrol */ 755 for (i = 0; i < path->sink->num_kcontrols; i++) { 756 if (!strcmp(control_name, path->sink->kcontrol_news[i].name)) { 757 path->name = path->sink->kcontrol_news[i].name; 758 dapm_set_mixer_path_status(path, i); 759 return 0; 760 } 761 } 762 return -ENODEV; 763} 764 765static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm, 766 struct snd_soc_dapm_widget *kcontrolw, 767 const struct snd_kcontrol_new *kcontrol_new, 768 struct snd_kcontrol **kcontrol) 769{ 770 struct snd_soc_dapm_widget *w; 771 int i; 772 773 *kcontrol = NULL; 774 775 list_for_each_entry(w, &dapm->card->widgets, list) { 776 if (w == kcontrolw || w->dapm != kcontrolw->dapm) 777 continue; 778 for (i = 0; i < w->num_kcontrols; i++) { 779 if (&w->kcontrol_news[i] == kcontrol_new) { 780 if (w->kcontrols) 781 *kcontrol = w->kcontrols[i]; 782 return 1; 783 } 784 } 785 } 786 787 return 0; 788} 789 790/* 791 * Determine if a kcontrol is shared. If it is, look it up. If it isn't, 792 * create it. Either way, add the widget into the control's widget list 793 */ 794static int dapm_create_or_share_kcontrol(struct snd_soc_dapm_widget *w, 795 int kci) 796{ 797 struct snd_soc_dapm_context *dapm = w->dapm; 798 struct snd_card *card = dapm->card->snd_card; 799 const char *prefix; 800 size_t prefix_len; 801 int shared; 802 struct snd_kcontrol *kcontrol; 803 bool wname_in_long_name, kcname_in_long_name; 804 char *long_name = NULL; 805 const char *name; 806 int ret = 0; 807 808 prefix = soc_dapm_prefix(dapm); 809 if (prefix) 810 prefix_len = strlen(prefix) + 1; 811 else 812 prefix_len = 0; 813 814 shared = dapm_is_shared_kcontrol(dapm, w, &w->kcontrol_news[kci], 815 &kcontrol); 816 817 if (!kcontrol) { 818 if (shared) { 819 wname_in_long_name = false; 820 kcname_in_long_name = true; 821 } else { 822 switch (w->id) { 823 case snd_soc_dapm_switch: 824 case snd_soc_dapm_mixer: 825 case snd_soc_dapm_pga: 826 wname_in_long_name = true; 827 kcname_in_long_name = true; 828 break; 829 case snd_soc_dapm_mixer_named_ctl: 830 wname_in_long_name = false; 831 kcname_in_long_name = true; 832 break; 833 case snd_soc_dapm_demux: 834 case snd_soc_dapm_mux: 835 wname_in_long_name = true; 836 kcname_in_long_name = false; 837 break; 838 default: 839 return -EINVAL; 840 } 841 } 842 843 if (wname_in_long_name && kcname_in_long_name) { 844 /* 845 * The control will get a prefix from the control 846 * creation process but we're also using the same 847 * prefix for widgets so cut the prefix off the 848 * front of the widget name. 849 */ 850 long_name = kasprintf(GFP_KERNEL, "%s %s", 851 w->name + prefix_len, 852 w->kcontrol_news[kci].name); 853 if (long_name == NULL) 854 return -ENOMEM; 855 856 name = long_name; 857 } else if (wname_in_long_name) { 858 long_name = NULL; 859 name = w->name + prefix_len; 860 } else { 861 long_name = NULL; 862 name = w->kcontrol_news[kci].name; 863 } 864 865 kcontrol = snd_soc_cnew(&w->kcontrol_news[kci], NULL, name, 866 prefix); 867 if (!kcontrol) { 868 ret = -ENOMEM; 869 goto exit_free; 870 } 871 872 kcontrol->private_free = dapm_kcontrol_free; 873 874 ret = dapm_kcontrol_data_alloc(w, kcontrol); 875 if (ret) { 876 snd_ctl_free_one(kcontrol); 877 goto exit_free; 878 } 879 880 ret = snd_ctl_add(card, kcontrol); 881 if (ret < 0) { 882 dev_err(dapm->dev, 883 "ASoC: failed to add widget %s dapm kcontrol %s: %d\n", 884 w->name, name, ret); 885 goto exit_free; 886 } 887 } 888 889 ret = dapm_kcontrol_add_widget(kcontrol, w); 890 if (ret == 0) 891 w->kcontrols[kci] = kcontrol; 892 893exit_free: 894 kfree(long_name); 895 896 return ret; 897} 898 899/* create new dapm mixer control */ 900static int dapm_new_mixer(struct snd_soc_dapm_widget *w) 901{ 902 int i, ret; 903 struct snd_soc_dapm_path *path; 904 struct dapm_kcontrol_data *data; 905 906 /* add kcontrol */ 907 for (i = 0; i < w->num_kcontrols; i++) { 908 /* match name */ 909 snd_soc_dapm_widget_for_each_source_path(w, path) { 910 /* mixer/mux paths name must match control name */ 911 if (path->name != (char *)w->kcontrol_news[i].name) 912 continue; 913 914 if (!w->kcontrols[i]) { 915 ret = dapm_create_or_share_kcontrol(w, i); 916 if (ret < 0) 917 return ret; 918 } 919 920 dapm_kcontrol_add_path(w->kcontrols[i], path); 921 922 data = snd_kcontrol_chip(w->kcontrols[i]); 923 if (data->widget) 924 snd_soc_dapm_add_path(data->widget->dapm, 925 data->widget, 926 path->source, 927 NULL, NULL); 928 } 929 } 930 931 return 0; 932} 933 934/* create new dapm mux control */ 935static int dapm_new_mux(struct snd_soc_dapm_widget *w) 936{ 937 struct snd_soc_dapm_context *dapm = w->dapm; 938 enum snd_soc_dapm_direction dir; 939 struct snd_soc_dapm_path *path; 940 const char *type; 941 int ret; 942 943 switch (w->id) { 944 case snd_soc_dapm_mux: 945 dir = SND_SOC_DAPM_DIR_OUT; 946 type = "mux"; 947 break; 948 case snd_soc_dapm_demux: 949 dir = SND_SOC_DAPM_DIR_IN; 950 type = "demux"; 951 break; 952 default: 953 return -EINVAL; 954 } 955 956 if (w->num_kcontrols != 1) { 957 dev_err(dapm->dev, 958 "ASoC: %s %s has incorrect number of controls\n", type, 959 w->name); 960 return -EINVAL; 961 } 962 963 if (list_empty(&w->edges[dir])) { 964 dev_err(dapm->dev, "ASoC: %s %s has no paths\n", type, w->name); 965 return -EINVAL; 966 } 967 968 ret = dapm_create_or_share_kcontrol(w, 0); 969 if (ret < 0) 970 return ret; 971 972 snd_soc_dapm_widget_for_each_path(w, dir, path) { 973 if (path->name) 974 dapm_kcontrol_add_path(w->kcontrols[0], path); 975 } 976 977 return 0; 978} 979 980/* create new dapm volume control */ 981static int dapm_new_pga(struct snd_soc_dapm_widget *w) 982{ 983 int i, ret; 984 985 for (i = 0; i < w->num_kcontrols; i++) { 986 ret = dapm_create_or_share_kcontrol(w, i); 987 if (ret < 0) 988 return ret; 989 } 990 991 return 0; 992} 993 994/* create new dapm dai link control */ 995static int dapm_new_dai_link(struct snd_soc_dapm_widget *w) 996{ 997 int i, ret; 998 struct snd_kcontrol *kcontrol; 999 struct snd_soc_dapm_context *dapm = w->dapm; 1000 struct snd_card *card = dapm->card->snd_card; 1001 1002 /* create control for links with > 1 config */ 1003 if (w->num_params <= 1) 1004 return 0; 1005 1006 /* add kcontrol */ 1007 for (i = 0; i < w->num_kcontrols; i++) { 1008 kcontrol = snd_soc_cnew(&w->kcontrol_news[i], w, 1009 w->name, NULL); 1010 ret = snd_ctl_add(card, kcontrol); 1011 if (ret < 0) { 1012 dev_err(dapm->dev, 1013 "ASoC: failed to add widget %s dapm kcontrol %s: %d\n", 1014 w->name, w->kcontrol_news[i].name, ret); 1015 return ret; 1016 } 1017 kcontrol->private_data = w; 1018 w->kcontrols[i] = kcontrol; 1019 } 1020 1021 return 0; 1022} 1023 1024/* We implement power down on suspend by checking the power state of 1025 * the ALSA card - when we are suspending the ALSA state for the card 1026 * is set to D3. 1027 */ 1028static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget) 1029{ 1030 int level = snd_power_get_state(widget->dapm->card->snd_card); 1031 1032 switch (level) { 1033 case SNDRV_CTL_POWER_D3hot: 1034 case SNDRV_CTL_POWER_D3cold: 1035 if (widget->ignore_suspend) 1036 dev_dbg(widget->dapm->dev, "ASoC: %s ignoring suspend\n", 1037 widget->name); 1038 return widget->ignore_suspend; 1039 default: 1040 return 1; 1041 } 1042} 1043 1044static int dapm_widget_list_create(struct snd_soc_dapm_widget_list **list, 1045 struct list_head *widgets) 1046{ 1047 struct snd_soc_dapm_widget *w; 1048 struct list_head *it; 1049 unsigned int size = 0; 1050 unsigned int i = 0; 1051 1052 list_for_each(it, widgets) 1053 size++; 1054 1055 *list = kzalloc(sizeof(**list) + size * sizeof(*w), GFP_KERNEL); 1056 if (*list == NULL) 1057 return -ENOMEM; 1058 1059 list_for_each_entry(w, widgets, work_list) 1060 (*list)->widgets[i++] = w; 1061 1062 (*list)->num_widgets = i; 1063 1064 return 0; 1065} 1066 1067/* 1068 * Common implementation for is_connected_output_ep() and 1069 * is_connected_input_ep(). The function is inlined since the combined size of 1070 * the two specialized functions is only marginally larger then the size of the 1071 * generic function and at the same time the fast path of the specialized 1072 * functions is significantly smaller than the generic function. 1073 */ 1074static __always_inline int is_connected_ep(struct snd_soc_dapm_widget *widget, 1075 struct list_head *list, enum snd_soc_dapm_direction dir, 1076 int (*fn)(struct snd_soc_dapm_widget *, struct list_head *)) 1077{ 1078 enum snd_soc_dapm_direction rdir = SND_SOC_DAPM_DIR_REVERSE(dir); 1079 struct snd_soc_dapm_path *path; 1080 int con = 0; 1081 1082 if (widget->endpoints[dir] >= 0) 1083 return widget->endpoints[dir]; 1084 1085 DAPM_UPDATE_STAT(widget, path_checks); 1086 1087 /* do we need to add this widget to the list ? */ 1088 if (list) 1089 list_add_tail(&widget->work_list, list); 1090 1091 if ((widget->is_ep & SND_SOC_DAPM_DIR_TO_EP(dir)) && widget->connected) { 1092 widget->endpoints[dir] = snd_soc_dapm_suspend_check(widget); 1093 return widget->endpoints[dir]; 1094 } 1095 1096 snd_soc_dapm_widget_for_each_path(widget, rdir, path) { 1097 DAPM_UPDATE_STAT(widget, neighbour_checks); 1098 1099 if (path->weak || path->is_supply) 1100 continue; 1101 1102 if (path->walking) 1103 return 1; 1104 1105 trace_snd_soc_dapm_path(widget, dir, path); 1106 1107 if (path->connect) { 1108 path->walking = 1; 1109 con += fn(path->node[dir], list); 1110 path->walking = 0; 1111 } 1112 } 1113 1114 widget->endpoints[dir] = con; 1115 1116 return con; 1117} 1118 1119/* 1120 * Recursively check for a completed path to an active or physically connected 1121 * output widget. Returns number of complete paths. 1122 */ 1123static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, 1124 struct list_head *list) 1125{ 1126 return is_connected_ep(widget, list, SND_SOC_DAPM_DIR_OUT, 1127 is_connected_output_ep); 1128} 1129 1130/* 1131 * Recursively check for a completed path to an active or physically connected 1132 * input widget. Returns number of complete paths. 1133 */ 1134static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, 1135 struct list_head *list) 1136{ 1137 return is_connected_ep(widget, list, SND_SOC_DAPM_DIR_IN, 1138 is_connected_input_ep); 1139} 1140 1141/** 1142 * snd_soc_dapm_get_connected_widgets - query audio path and it's widgets. 1143 * @dai: the soc DAI. 1144 * @stream: stream direction. 1145 * @list: list of active widgets for this stream. 1146 * 1147 * Queries DAPM graph as to whether an valid audio stream path exists for 1148 * the initial stream specified by name. This takes into account 1149 * current mixer and mux kcontrol settings. Creates list of valid widgets. 1150 * 1151 * Returns the number of valid paths or negative error. 1152 */ 1153int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream, 1154 struct snd_soc_dapm_widget_list **list) 1155{ 1156 struct snd_soc_card *card = dai->component->card; 1157 struct snd_soc_dapm_widget *w; 1158 LIST_HEAD(widgets); 1159 int paths; 1160 int ret; 1161 1162 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 1163 1164 /* 1165 * For is_connected_{output,input}_ep fully discover the graph we need 1166 * to reset the cached number of inputs and outputs. 1167 */ 1168 list_for_each_entry(w, &card->widgets, list) { 1169 w->endpoints[SND_SOC_DAPM_DIR_IN] = -1; 1170 w->endpoints[SND_SOC_DAPM_DIR_OUT] = -1; 1171 } 1172 1173 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 1174 paths = is_connected_output_ep(dai->playback_widget, &widgets); 1175 else 1176 paths = is_connected_input_ep(dai->capture_widget, &widgets); 1177 1178 /* Drop starting point */ 1179 list_del(widgets.next); 1180 1181 ret = dapm_widget_list_create(list, &widgets); 1182 if (ret) 1183 paths = ret; 1184 1185 trace_snd_soc_dapm_connected(paths, stream); 1186 mutex_unlock(&card->dapm_mutex); 1187 1188 return paths; 1189} 1190 1191/* 1192 * Handler for regulator supply widget. 1193 */ 1194int dapm_regulator_event(struct snd_soc_dapm_widget *w, 1195 struct snd_kcontrol *kcontrol, int event) 1196{ 1197 int ret; 1198 1199 soc_dapm_async_complete(w->dapm); 1200 1201 if (SND_SOC_DAPM_EVENT_ON(event)) { 1202 if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) { 1203 ret = regulator_allow_bypass(w->regulator, false); 1204 if (ret != 0) 1205 dev_warn(w->dapm->dev, 1206 "ASoC: Failed to unbypass %s: %d\n", 1207 w->name, ret); 1208 } 1209 1210 return regulator_enable(w->regulator); 1211 } else { 1212 if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) { 1213 ret = regulator_allow_bypass(w->regulator, true); 1214 if (ret != 0) 1215 dev_warn(w->dapm->dev, 1216 "ASoC: Failed to bypass %s: %d\n", 1217 w->name, ret); 1218 } 1219 1220 return regulator_disable_deferred(w->regulator, w->shift); 1221 } 1222} 1223EXPORT_SYMBOL_GPL(dapm_regulator_event); 1224 1225/* 1226 * Handler for clock supply widget. 1227 */ 1228int dapm_clock_event(struct snd_soc_dapm_widget *w, 1229 struct snd_kcontrol *kcontrol, int event) 1230{ 1231 if (!w->clk) 1232 return -EIO; 1233 1234 soc_dapm_async_complete(w->dapm); 1235 1236#ifdef CONFIG_HAVE_CLK 1237 if (SND_SOC_DAPM_EVENT_ON(event)) { 1238 return clk_prepare_enable(w->clk); 1239 } else { 1240 clk_disable_unprepare(w->clk); 1241 return 0; 1242 } 1243#endif 1244 return 0; 1245} 1246EXPORT_SYMBOL_GPL(dapm_clock_event); 1247 1248static int dapm_widget_power_check(struct snd_soc_dapm_widget *w) 1249{ 1250 if (w->power_checked) 1251 return w->new_power; 1252 1253 if (w->force) 1254 w->new_power = 1; 1255 else 1256 w->new_power = w->power_check(w); 1257 1258 w->power_checked = true; 1259 1260 return w->new_power; 1261} 1262 1263/* Generic check to see if a widget should be powered. 1264 */ 1265static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) 1266{ 1267 int in, out; 1268 1269 DAPM_UPDATE_STAT(w, power_checks); 1270 1271 in = is_connected_input_ep(w, NULL); 1272 out = is_connected_output_ep(w, NULL); 1273 return out != 0 && in != 0; 1274} 1275 1276/* Check to see if a power supply is needed */ 1277static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) 1278{ 1279 struct snd_soc_dapm_path *path; 1280 1281 DAPM_UPDATE_STAT(w, power_checks); 1282 1283 /* Check if one of our outputs is connected */ 1284 snd_soc_dapm_widget_for_each_sink_path(w, path) { 1285 DAPM_UPDATE_STAT(w, neighbour_checks); 1286 1287 if (path->weak) 1288 continue; 1289 1290 if (path->connected && 1291 !path->connected(path->source, path->sink)) 1292 continue; 1293 1294 if (dapm_widget_power_check(path->sink)) 1295 return 1; 1296 } 1297 1298 return 0; 1299} 1300 1301static int dapm_always_on_check_power(struct snd_soc_dapm_widget *w) 1302{ 1303 return 1; 1304} 1305 1306static int dapm_seq_compare(struct snd_soc_dapm_widget *a, 1307 struct snd_soc_dapm_widget *b, 1308 bool power_up) 1309{ 1310 int *sort; 1311 1312 if (power_up) 1313 sort = dapm_up_seq; 1314 else 1315 sort = dapm_down_seq; 1316 1317 if (sort[a->id] != sort[b->id]) 1318 return sort[a->id] - sort[b->id]; 1319 if (a->subseq != b->subseq) { 1320 if (power_up) 1321 return a->subseq - b->subseq; 1322 else 1323 return b->subseq - a->subseq; 1324 } 1325 if (a->reg != b->reg) 1326 return a->reg - b->reg; 1327 if (a->dapm != b->dapm) 1328 return (unsigned long)a->dapm - (unsigned long)b->dapm; 1329 1330 return 0; 1331} 1332 1333/* Insert a widget in order into a DAPM power sequence. */ 1334static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget, 1335 struct list_head *list, 1336 bool power_up) 1337{ 1338 struct snd_soc_dapm_widget *w; 1339 1340 list_for_each_entry(w, list, power_list) 1341 if (dapm_seq_compare(new_widget, w, power_up) < 0) { 1342 list_add_tail(&new_widget->power_list, &w->power_list); 1343 return; 1344 } 1345 1346 list_add_tail(&new_widget->power_list, list); 1347} 1348 1349static void dapm_seq_check_event(struct snd_soc_card *card, 1350 struct snd_soc_dapm_widget *w, int event) 1351{ 1352 const char *ev_name; 1353 int power, ret; 1354 1355 switch (event) { 1356 case SND_SOC_DAPM_PRE_PMU: 1357 ev_name = "PRE_PMU"; 1358 power = 1; 1359 break; 1360 case SND_SOC_DAPM_POST_PMU: 1361 ev_name = "POST_PMU"; 1362 power = 1; 1363 break; 1364 case SND_SOC_DAPM_PRE_PMD: 1365 ev_name = "PRE_PMD"; 1366 power = 0; 1367 break; 1368 case SND_SOC_DAPM_POST_PMD: 1369 ev_name = "POST_PMD"; 1370 power = 0; 1371 break; 1372 case SND_SOC_DAPM_WILL_PMU: 1373 ev_name = "WILL_PMU"; 1374 power = 1; 1375 break; 1376 case SND_SOC_DAPM_WILL_PMD: 1377 ev_name = "WILL_PMD"; 1378 power = 0; 1379 break; 1380 default: 1381 WARN(1, "Unknown event %d\n", event); 1382 return; 1383 } 1384 1385 if (w->new_power != power) 1386 return; 1387 1388 if (w->event && (w->event_flags & event)) { 1389 pop_dbg(w->dapm->dev, card->pop_time, "pop test : %s %s\n", 1390 w->name, ev_name); 1391 soc_dapm_async_complete(w->dapm); 1392 trace_snd_soc_dapm_widget_event_start(w, event); 1393 ret = w->event(w, NULL, event); 1394 trace_snd_soc_dapm_widget_event_done(w, event); 1395 if (ret < 0) 1396 dev_err(w->dapm->dev, "ASoC: %s: %s event failed: %d\n", 1397 ev_name, w->name, ret); 1398 } 1399} 1400 1401/* Apply the coalesced changes from a DAPM sequence */ 1402static void dapm_seq_run_coalesced(struct snd_soc_card *card, 1403 struct list_head *pending) 1404{ 1405 struct snd_soc_dapm_context *dapm; 1406 struct snd_soc_dapm_widget *w; 1407 int reg; 1408 unsigned int value = 0; 1409 unsigned int mask = 0; 1410 1411 w = list_first_entry(pending, struct snd_soc_dapm_widget, power_list); 1412 reg = w->reg; 1413 dapm = w->dapm; 1414 1415 list_for_each_entry(w, pending, power_list) { 1416 WARN_ON(reg != w->reg || dapm != w->dapm); 1417 w->power = w->new_power; 1418 1419 mask |= w->mask << w->shift; 1420 if (w->power) 1421 value |= w->on_val << w->shift; 1422 else 1423 value |= w->off_val << w->shift; 1424 1425 pop_dbg(dapm->dev, card->pop_time, 1426 "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n", 1427 w->name, reg, value, mask); 1428 1429 /* Check for events */ 1430 dapm_seq_check_event(card, w, SND_SOC_DAPM_PRE_PMU); 1431 dapm_seq_check_event(card, w, SND_SOC_DAPM_PRE_PMD); 1432 } 1433 1434 if (reg >= 0) { 1435 /* Any widget will do, they should all be updating the 1436 * same register. 1437 */ 1438 1439 pop_dbg(dapm->dev, card->pop_time, 1440 "pop test : Applying 0x%x/0x%x to %x in %dms\n", 1441 value, mask, reg, card->pop_time); 1442 pop_wait(card->pop_time); 1443 soc_dapm_update_bits(dapm, reg, mask, value); 1444 } 1445 1446 list_for_each_entry(w, pending, power_list) { 1447 dapm_seq_check_event(card, w, SND_SOC_DAPM_POST_PMU); 1448 dapm_seq_check_event(card, w, SND_SOC_DAPM_POST_PMD); 1449 } 1450} 1451 1452/* Apply a DAPM power sequence. 1453 * 1454 * We walk over a pre-sorted list of widgets to apply power to. In 1455 * order to minimise the number of writes to the device required 1456 * multiple widgets will be updated in a single write where possible. 1457 * Currently anything that requires more than a single write is not 1458 * handled. 1459 */ 1460static void dapm_seq_run(struct snd_soc_card *card, 1461 struct list_head *list, int event, bool power_up) 1462{ 1463 struct snd_soc_dapm_widget *w, *n; 1464 struct snd_soc_dapm_context *d; 1465 LIST_HEAD(pending); 1466 int cur_sort = -1; 1467 int cur_subseq = -1; 1468 int cur_reg = SND_SOC_NOPM; 1469 struct snd_soc_dapm_context *cur_dapm = NULL; 1470 int ret, i; 1471 int *sort; 1472 1473 if (power_up) 1474 sort = dapm_up_seq; 1475 else 1476 sort = dapm_down_seq; 1477 1478 list_for_each_entry_safe(w, n, list, power_list) { 1479 ret = 0; 1480 1481 /* Do we need to apply any queued changes? */ 1482 if (sort[w->id] != cur_sort || w->reg != cur_reg || 1483 w->dapm != cur_dapm || w->subseq != cur_subseq) { 1484 if (!list_empty(&pending)) 1485 dapm_seq_run_coalesced(card, &pending); 1486 1487 if (cur_dapm && cur_dapm->seq_notifier) { 1488 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++) 1489 if (sort[i] == cur_sort) 1490 cur_dapm->seq_notifier(cur_dapm, 1491 i, 1492 cur_subseq); 1493 } 1494 1495 if (cur_dapm && w->dapm != cur_dapm) 1496 soc_dapm_async_complete(cur_dapm); 1497 1498 INIT_LIST_HEAD(&pending); 1499 cur_sort = -1; 1500 cur_subseq = INT_MIN; 1501 cur_reg = SND_SOC_NOPM; 1502 cur_dapm = NULL; 1503 } 1504 1505 switch (w->id) { 1506 case snd_soc_dapm_pre: 1507 if (!w->event) 1508 list_for_each_entry_safe_continue(w, n, list, 1509 power_list); 1510 1511 if (event == SND_SOC_DAPM_STREAM_START) 1512 ret = w->event(w, 1513 NULL, SND_SOC_DAPM_PRE_PMU); 1514 else if (event == SND_SOC_DAPM_STREAM_STOP) 1515 ret = w->event(w, 1516 NULL, SND_SOC_DAPM_PRE_PMD); 1517 break; 1518 1519 case snd_soc_dapm_post: 1520 if (!w->event) 1521 list_for_each_entry_safe_continue(w, n, list, 1522 power_list); 1523 1524 if (event == SND_SOC_DAPM_STREAM_START) 1525 ret = w->event(w, 1526 NULL, SND_SOC_DAPM_POST_PMU); 1527 else if (event == SND_SOC_DAPM_STREAM_STOP) 1528 ret = w->event(w, 1529 NULL, SND_SOC_DAPM_POST_PMD); 1530 break; 1531 1532 default: 1533 /* Queue it up for application */ 1534 cur_sort = sort[w->id]; 1535 cur_subseq = w->subseq; 1536 cur_reg = w->reg; 1537 cur_dapm = w->dapm; 1538 list_move(&w->power_list, &pending); 1539 break; 1540 } 1541 1542 if (ret < 0) 1543 dev_err(w->dapm->dev, 1544 "ASoC: Failed to apply widget power: %d\n", ret); 1545 } 1546 1547 if (!list_empty(&pending)) 1548 dapm_seq_run_coalesced(card, &pending); 1549 1550 if (cur_dapm && cur_dapm->seq_notifier) { 1551 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++) 1552 if (sort[i] == cur_sort) 1553 cur_dapm->seq_notifier(cur_dapm, 1554 i, cur_subseq); 1555 } 1556 1557 list_for_each_entry(d, &card->dapm_list, list) { 1558 soc_dapm_async_complete(d); 1559 } 1560} 1561 1562static void dapm_widget_update(struct snd_soc_card *card) 1563{ 1564 struct snd_soc_dapm_update *update = card->update; 1565 struct snd_soc_dapm_widget_list *wlist; 1566 struct snd_soc_dapm_widget *w = NULL; 1567 unsigned int wi; 1568 int ret; 1569 1570 if (!update || !dapm_kcontrol_is_powered(update->kcontrol)) 1571 return; 1572 1573 wlist = dapm_kcontrol_get_wlist(update->kcontrol); 1574 1575 for (wi = 0; wi < wlist->num_widgets; wi++) { 1576 w = wlist->widgets[wi]; 1577 1578 if (w->event && (w->event_flags & SND_SOC_DAPM_PRE_REG)) { 1579 ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG); 1580 if (ret != 0) 1581 dev_err(w->dapm->dev, "ASoC: %s DAPM pre-event failed: %d\n", 1582 w->name, ret); 1583 } 1584 } 1585 1586 if (!w) 1587 return; 1588 1589 ret = soc_dapm_update_bits(w->dapm, update->reg, update->mask, 1590 update->val); 1591 if (ret < 0) 1592 dev_err(w->dapm->dev, "ASoC: %s DAPM update failed: %d\n", 1593 w->name, ret); 1594 1595 for (wi = 0; wi < wlist->num_widgets; wi++) { 1596 w = wlist->widgets[wi]; 1597 1598 if (w->event && (w->event_flags & SND_SOC_DAPM_POST_REG)) { 1599 ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG); 1600 if (ret != 0) 1601 dev_err(w->dapm->dev, "ASoC: %s DAPM post-event failed: %d\n", 1602 w->name, ret); 1603 } 1604 } 1605} 1606 1607/* Async callback run prior to DAPM sequences - brings to _PREPARE if 1608 * they're changing state. 1609 */ 1610static void dapm_pre_sequence_async(void *data, async_cookie_t cookie) 1611{ 1612 struct snd_soc_dapm_context *d = data; 1613 int ret; 1614 1615 /* If we're off and we're not supposed to be go into STANDBY */ 1616 if (d->bias_level == SND_SOC_BIAS_OFF && 1617 d->target_bias_level != SND_SOC_BIAS_OFF) { 1618 if (d->dev) 1619 pm_runtime_get_sync(d->dev); 1620 1621 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY); 1622 if (ret != 0) 1623 dev_err(d->dev, 1624 "ASoC: Failed to turn on bias: %d\n", ret); 1625 } 1626 1627 /* Prepare for a transition to ON or away from ON */ 1628 if ((d->target_bias_level == SND_SOC_BIAS_ON && 1629 d->bias_level != SND_SOC_BIAS_ON) || 1630 (d->target_bias_level != SND_SOC_BIAS_ON && 1631 d->bias_level == SND_SOC_BIAS_ON)) { 1632 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_PREPARE); 1633 if (ret != 0) 1634 dev_err(d->dev, 1635 "ASoC: Failed to prepare bias: %d\n", ret); 1636 } 1637} 1638 1639/* Async callback run prior to DAPM sequences - brings to their final 1640 * state. 1641 */ 1642static void dapm_post_sequence_async(void *data, async_cookie_t cookie) 1643{ 1644 struct snd_soc_dapm_context *d = data; 1645 int ret; 1646 1647 /* If we just powered the last thing off drop to standby bias */ 1648 if (d->bias_level == SND_SOC_BIAS_PREPARE && 1649 (d->target_bias_level == SND_SOC_BIAS_STANDBY || 1650 d->target_bias_level == SND_SOC_BIAS_OFF)) { 1651 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY); 1652 if (ret != 0) 1653 dev_err(d->dev, "ASoC: Failed to apply standby bias: %d\n", 1654 ret); 1655 } 1656 1657 /* If we're in standby and can support bias off then do that */ 1658 if (d->bias_level == SND_SOC_BIAS_STANDBY && 1659 d->target_bias_level == SND_SOC_BIAS_OFF) { 1660 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_OFF); 1661 if (ret != 0) 1662 dev_err(d->dev, "ASoC: Failed to turn off bias: %d\n", 1663 ret); 1664 1665 if (d->dev) 1666 pm_runtime_put(d->dev); 1667 } 1668 1669 /* If we just powered up then move to active bias */ 1670 if (d->bias_level == SND_SOC_BIAS_PREPARE && 1671 d->target_bias_level == SND_SOC_BIAS_ON) { 1672 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_ON); 1673 if (ret != 0) 1674 dev_err(d->dev, "ASoC: Failed to apply active bias: %d\n", 1675 ret); 1676 } 1677} 1678 1679static void dapm_widget_set_peer_power(struct snd_soc_dapm_widget *peer, 1680 bool power, bool connect) 1681{ 1682 /* If a connection is being made or broken then that update 1683 * will have marked the peer dirty, otherwise the widgets are 1684 * not connected and this update has no impact. */ 1685 if (!connect) 1686 return; 1687 1688 /* If the peer is already in the state we're moving to then we 1689 * won't have an impact on it. */ 1690 if (power != peer->power) 1691 dapm_mark_dirty(peer, "peer state change"); 1692} 1693 1694static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power, 1695 struct list_head *up_list, 1696 struct list_head *down_list) 1697{ 1698 struct snd_soc_dapm_path *path; 1699 1700 if (w->power == power) 1701 return; 1702 1703 trace_snd_soc_dapm_widget_power(w, power); 1704 1705 /* If we changed our power state perhaps our neigbours changed 1706 * also. 1707 */ 1708 snd_soc_dapm_widget_for_each_source_path(w, path) 1709 dapm_widget_set_peer_power(path->source, power, path->connect); 1710 1711 /* Supplies can't affect their outputs, only their inputs */ 1712 if (!w->is_supply) { 1713 snd_soc_dapm_widget_for_each_sink_path(w, path) 1714 dapm_widget_set_peer_power(path->sink, power, 1715 path->connect); 1716 } 1717 1718 if (power) 1719 dapm_seq_insert(w, up_list, true); 1720 else 1721 dapm_seq_insert(w, down_list, false); 1722} 1723 1724static void dapm_power_one_widget(struct snd_soc_dapm_widget *w, 1725 struct list_head *up_list, 1726 struct list_head *down_list) 1727{ 1728 int power; 1729 1730 switch (w->id) { 1731 case snd_soc_dapm_pre: 1732 dapm_seq_insert(w, down_list, false); 1733 break; 1734 case snd_soc_dapm_post: 1735 dapm_seq_insert(w, up_list, true); 1736 break; 1737 1738 default: 1739 power = dapm_widget_power_check(w); 1740 1741 dapm_widget_set_power(w, power, up_list, down_list); 1742 break; 1743 } 1744} 1745 1746static bool dapm_idle_bias_off(struct snd_soc_dapm_context *dapm) 1747{ 1748 if (dapm->idle_bias_off) 1749 return true; 1750 1751 switch (snd_power_get_state(dapm->card->snd_card)) { 1752 case SNDRV_CTL_POWER_D3hot: 1753 case SNDRV_CTL_POWER_D3cold: 1754 return dapm->suspend_bias_off; 1755 default: 1756 break; 1757 } 1758 1759 return false; 1760} 1761 1762/* 1763 * Scan each dapm widget for complete audio path. 1764 * A complete path is a route that has valid endpoints i.e.:- 1765 * 1766 * o DAC to output pin. 1767 * o Input Pin to ADC. 1768 * o Input pin to Output pin (bypass, sidetone) 1769 * o DAC to ADC (loopback). 1770 */ 1771static int dapm_power_widgets(struct snd_soc_card *card, int event) 1772{ 1773 struct snd_soc_dapm_widget *w; 1774 struct snd_soc_dapm_context *d; 1775 LIST_HEAD(up_list); 1776 LIST_HEAD(down_list); 1777 ASYNC_DOMAIN_EXCLUSIVE(async_domain); 1778 enum snd_soc_bias_level bias; 1779 1780 lockdep_assert_held(&card->dapm_mutex); 1781 1782 trace_snd_soc_dapm_start(card); 1783 1784 list_for_each_entry(d, &card->dapm_list, list) { 1785 if (dapm_idle_bias_off(d)) 1786 d->target_bias_level = SND_SOC_BIAS_OFF; 1787 else 1788 d->target_bias_level = SND_SOC_BIAS_STANDBY; 1789 } 1790 1791 dapm_reset(card); 1792 1793 /* Check which widgets we need to power and store them in 1794 * lists indicating if they should be powered up or down. We 1795 * only check widgets that have been flagged as dirty but note 1796 * that new widgets may be added to the dirty list while we 1797 * iterate. 1798 */ 1799 list_for_each_entry(w, &card->dapm_dirty, dirty) { 1800 dapm_power_one_widget(w, &up_list, &down_list); 1801 } 1802 1803 list_for_each_entry(w, &card->widgets, list) { 1804 switch (w->id) { 1805 case snd_soc_dapm_pre: 1806 case snd_soc_dapm_post: 1807 /* These widgets always need to be powered */ 1808 break; 1809 default: 1810 list_del_init(&w->dirty); 1811 break; 1812 } 1813 1814 if (w->new_power) { 1815 d = w->dapm; 1816 1817 /* Supplies and micbiases only bring the 1818 * context up to STANDBY as unless something 1819 * else is active and passing audio they 1820 * generally don't require full power. Signal 1821 * generators are virtual pins and have no 1822 * power impact themselves. 1823 */ 1824 switch (w->id) { 1825 case snd_soc_dapm_siggen: 1826 case snd_soc_dapm_vmid: 1827 break; 1828 case snd_soc_dapm_supply: 1829 case snd_soc_dapm_regulator_supply: 1830 case snd_soc_dapm_clock_supply: 1831 case snd_soc_dapm_micbias: 1832 if (d->target_bias_level < SND_SOC_BIAS_STANDBY) 1833 d->target_bias_level = SND_SOC_BIAS_STANDBY; 1834 break; 1835 default: 1836 d->target_bias_level = SND_SOC_BIAS_ON; 1837 break; 1838 } 1839 } 1840 1841 } 1842 1843 /* Force all contexts in the card to the same bias state if 1844 * they're not ground referenced. 1845 */ 1846 bias = SND_SOC_BIAS_OFF; 1847 list_for_each_entry(d, &card->dapm_list, list) 1848 if (d->target_bias_level > bias) 1849 bias = d->target_bias_level; 1850 list_for_each_entry(d, &card->dapm_list, list) 1851 if (!dapm_idle_bias_off(d)) 1852 d->target_bias_level = bias; 1853 1854 trace_snd_soc_dapm_walk_done(card); 1855 1856 /* Run card bias changes at first */ 1857 dapm_pre_sequence_async(&card->dapm, 0); 1858 /* Run other bias changes in parallel */ 1859 list_for_each_entry(d, &card->dapm_list, list) { 1860 if (d != &card->dapm) 1861 async_schedule_domain(dapm_pre_sequence_async, d, 1862 &async_domain); 1863 } 1864 async_synchronize_full_domain(&async_domain); 1865 1866 list_for_each_entry(w, &down_list, power_list) { 1867 dapm_seq_check_event(card, w, SND_SOC_DAPM_WILL_PMD); 1868 } 1869 1870 list_for_each_entry(w, &up_list, power_list) { 1871 dapm_seq_check_event(card, w, SND_SOC_DAPM_WILL_PMU); 1872 } 1873 1874 /* Power down widgets first; try to avoid amplifying pops. */ 1875 dapm_seq_run(card, &down_list, event, false); 1876 1877 dapm_widget_update(card); 1878 1879 /* Now power up. */ 1880 dapm_seq_run(card, &up_list, event, true); 1881 1882 /* Run all the bias changes in parallel */ 1883 list_for_each_entry(d, &card->dapm_list, list) { 1884 if (d != &card->dapm) 1885 async_schedule_domain(dapm_post_sequence_async, d, 1886 &async_domain); 1887 } 1888 async_synchronize_full_domain(&async_domain); 1889 /* Run card bias changes at last */ 1890 dapm_post_sequence_async(&card->dapm, 0); 1891 1892 /* do we need to notify any clients that DAPM event is complete */ 1893 list_for_each_entry(d, &card->dapm_list, list) { 1894 if (d->stream_event) 1895 d->stream_event(d, event); 1896 } 1897 1898 pop_dbg(card->dev, card->pop_time, 1899 "DAPM sequencing finished, waiting %dms\n", card->pop_time); 1900 pop_wait(card->pop_time); 1901 1902 trace_snd_soc_dapm_done(card); 1903 1904 return 0; 1905} 1906 1907#ifdef CONFIG_DEBUG_FS 1908static ssize_t dapm_widget_power_read_file(struct file *file, 1909 char __user *user_buf, 1910 size_t count, loff_t *ppos) 1911{ 1912 struct snd_soc_dapm_widget *w = file->private_data; 1913 struct snd_soc_card *card = w->dapm->card; 1914 enum snd_soc_dapm_direction dir, rdir; 1915 char *buf; 1916 int in, out; 1917 ssize_t ret; 1918 struct snd_soc_dapm_path *p = NULL; 1919 1920 buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 1921 if (!buf) 1922 return -ENOMEM; 1923 1924 mutex_lock(&card->dapm_mutex); 1925 1926 /* Supply widgets are not handled by is_connected_{input,output}_ep() */ 1927 if (w->is_supply) { 1928 in = 0; 1929 out = 0; 1930 } else { 1931 in = is_connected_input_ep(w, NULL); 1932 out = is_connected_output_ep(w, NULL); 1933 } 1934 1935 ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d", 1936 w->name, w->power ? "On" : "Off", 1937 w->force ? " (forced)" : "", in, out); 1938 1939 if (w->reg >= 0) 1940 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1941 " - R%d(0x%x) mask 0x%x", 1942 w->reg, w->reg, w->mask << w->shift); 1943 1944 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); 1945 1946 if (w->sname) 1947 ret += snprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n", 1948 w->sname, 1949 w->active ? "active" : "inactive"); 1950 1951 snd_soc_dapm_for_each_direction(dir) { 1952 rdir = SND_SOC_DAPM_DIR_REVERSE(dir); 1953 snd_soc_dapm_widget_for_each_path(w, dir, p) { 1954 if (p->connected && !p->connected(w, p->node[rdir])) 1955 continue; 1956 1957 if (!p->connect) 1958 continue; 1959 1960 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1961 " %s \"%s\" \"%s\"\n", 1962 (rdir == SND_SOC_DAPM_DIR_IN) ? "in" : "out", 1963 p->name ? p->name : "static", 1964 p->node[rdir]->name); 1965 } 1966 } 1967 1968 mutex_unlock(&card->dapm_mutex); 1969 1970 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); 1971 1972 kfree(buf); 1973 return ret; 1974} 1975 1976static const struct file_operations dapm_widget_power_fops = { 1977 .open = simple_open, 1978 .read = dapm_widget_power_read_file, 1979 .llseek = default_llseek, 1980}; 1981 1982static ssize_t dapm_bias_read_file(struct file *file, char __user *user_buf, 1983 size_t count, loff_t *ppos) 1984{ 1985 struct snd_soc_dapm_context *dapm = file->private_data; 1986 char *level; 1987 1988 switch (dapm->bias_level) { 1989 case SND_SOC_BIAS_ON: 1990 level = "On\n"; 1991 break; 1992 case SND_SOC_BIAS_PREPARE: 1993 level = "Prepare\n"; 1994 break; 1995 case SND_SOC_BIAS_STANDBY: 1996 level = "Standby\n"; 1997 break; 1998 case SND_SOC_BIAS_OFF: 1999 level = "Off\n"; 2000 break; 2001 default: 2002 WARN(1, "Unknown bias_level %d\n", dapm->bias_level); 2003 level = "Unknown\n"; 2004 break; 2005 } 2006 2007 return simple_read_from_buffer(user_buf, count, ppos, level, 2008 strlen(level)); 2009} 2010 2011static const struct file_operations dapm_bias_fops = { 2012 .open = simple_open, 2013 .read = dapm_bias_read_file, 2014 .llseek = default_llseek, 2015}; 2016 2017void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm, 2018 struct dentry *parent) 2019{ 2020 struct dentry *d; 2021 2022 if (!parent) 2023 return; 2024 2025 dapm->debugfs_dapm = debugfs_create_dir("dapm", parent); 2026 2027 if (!dapm->debugfs_dapm) { 2028 dev_warn(dapm->dev, 2029 "ASoC: Failed to create DAPM debugfs directory\n"); 2030 return; 2031 } 2032 2033 d = debugfs_create_file("bias_level", 0444, 2034 dapm->debugfs_dapm, dapm, 2035 &dapm_bias_fops); 2036 if (!d) 2037 dev_warn(dapm->dev, 2038 "ASoC: Failed to create bias level debugfs file\n"); 2039} 2040 2041static void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w) 2042{ 2043 struct snd_soc_dapm_context *dapm = w->dapm; 2044 struct dentry *d; 2045 2046 if (!dapm->debugfs_dapm || !w->name) 2047 return; 2048 2049 d = debugfs_create_file(w->name, 0444, 2050 dapm->debugfs_dapm, w, 2051 &dapm_widget_power_fops); 2052 if (!d) 2053 dev_warn(w->dapm->dev, 2054 "ASoC: Failed to create %s debugfs file\n", 2055 w->name); 2056} 2057 2058static void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm) 2059{ 2060 debugfs_remove_recursive(dapm->debugfs_dapm); 2061} 2062 2063#else 2064void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm, 2065 struct dentry *parent) 2066{ 2067} 2068 2069static inline void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w) 2070{ 2071} 2072 2073static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm) 2074{ 2075} 2076 2077#endif 2078 2079/* 2080 * soc_dapm_connect_path() - Connects or disconnects a path 2081 * @path: The path to update 2082 * @connect: The new connect state of the path. True if the path is connected, 2083 * false if it is disconneted. 2084 * @reason: The reason why the path changed (for debugging only) 2085 */ 2086static void soc_dapm_connect_path(struct snd_soc_dapm_path *path, 2087 bool connect, const char *reason) 2088{ 2089 if (path->connect == connect) 2090 return; 2091 2092 path->connect = connect; 2093 dapm_mark_dirty(path->source, reason); 2094 dapm_mark_dirty(path->sink, reason); 2095 dapm_path_invalidate(path); 2096} 2097 2098/* test and update the power status of a mux widget */ 2099static int soc_dapm_mux_update_power(struct snd_soc_card *card, 2100 struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e) 2101{ 2102 struct snd_soc_dapm_path *path; 2103 int found = 0; 2104 bool connect; 2105 2106 lockdep_assert_held(&card->dapm_mutex); 2107 2108 /* find dapm widget path assoc with kcontrol */ 2109 dapm_kcontrol_for_each_path(path, kcontrol) { 2110 found = 1; 2111 /* we now need to match the string in the enum to the path */ 2112 if (!(strcmp(path->name, e->texts[mux]))) 2113 connect = true; 2114 else 2115 connect = false; 2116 2117 soc_dapm_connect_path(path, connect, "mux update"); 2118 } 2119 2120 if (found) 2121 dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP); 2122 2123 return found; 2124} 2125 2126int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_context *dapm, 2127 struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e, 2128 struct snd_soc_dapm_update *update) 2129{ 2130 struct snd_soc_card *card = dapm->card; 2131 int ret; 2132 2133 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 2134 card->update = update; 2135 ret = soc_dapm_mux_update_power(card, kcontrol, mux, e); 2136 card->update = NULL; 2137 mutex_unlock(&card->dapm_mutex); 2138 if (ret > 0) 2139 soc_dpcm_runtime_update(card); 2140 return ret; 2141} 2142EXPORT_SYMBOL_GPL(snd_soc_dapm_mux_update_power); 2143 2144/* test and update the power status of a mixer or switch widget */ 2145static int soc_dapm_mixer_update_power(struct snd_soc_card *card, 2146 struct snd_kcontrol *kcontrol, int connect) 2147{ 2148 struct snd_soc_dapm_path *path; 2149 int found = 0; 2150 2151 lockdep_assert_held(&card->dapm_mutex); 2152 2153 /* find dapm widget path assoc with kcontrol */ 2154 dapm_kcontrol_for_each_path(path, kcontrol) { 2155 found = 1; 2156 soc_dapm_connect_path(path, connect, "mixer update"); 2157 } 2158 2159 if (found) 2160 dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP); 2161 2162 return found; 2163} 2164 2165int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_context *dapm, 2166 struct snd_kcontrol *kcontrol, int connect, 2167 struct snd_soc_dapm_update *update) 2168{ 2169 struct snd_soc_card *card = dapm->card; 2170 int ret; 2171 2172 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 2173 card->update = update; 2174 ret = soc_dapm_mixer_update_power(card, kcontrol, connect); 2175 card->update = NULL; 2176 mutex_unlock(&card->dapm_mutex); 2177 if (ret > 0) 2178 soc_dpcm_runtime_update(card); 2179 return ret; 2180} 2181EXPORT_SYMBOL_GPL(snd_soc_dapm_mixer_update_power); 2182 2183static ssize_t dapm_widget_show_component(struct snd_soc_component *cmpnt, 2184 char *buf) 2185{ 2186 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cmpnt); 2187 struct snd_soc_dapm_widget *w; 2188 int count = 0; 2189 char *state = "not set"; 2190 2191 /* card won't be set for the dummy component, as a spot fix 2192 * we're checking for that case specifically here but in future 2193 * we will ensure that the dummy component looks like others. 2194 */ 2195 if (!cmpnt->card) 2196 return 0; 2197 2198 list_for_each_entry(w, &cmpnt->card->widgets, list) { 2199 if (w->dapm != dapm) 2200 continue; 2201 2202 /* only display widgets that burnm power */ 2203 switch (w->id) { 2204 case snd_soc_dapm_hp: 2205 case snd_soc_dapm_mic: 2206 case snd_soc_dapm_spk: 2207 case snd_soc_dapm_line: 2208 case snd_soc_dapm_micbias: 2209 case snd_soc_dapm_dac: 2210 case snd_soc_dapm_adc: 2211 case snd_soc_dapm_pga: 2212 case snd_soc_dapm_out_drv: 2213 case snd_soc_dapm_mixer: 2214 case snd_soc_dapm_mixer_named_ctl: 2215 case snd_soc_dapm_supply: 2216 case snd_soc_dapm_regulator_supply: 2217 case snd_soc_dapm_clock_supply: 2218 if (w->name) 2219 count += sprintf(buf + count, "%s: %s\n", 2220 w->name, w->power ? "On":"Off"); 2221 break; 2222 default: 2223 break; 2224 } 2225 } 2226 2227 switch (snd_soc_dapm_get_bias_level(dapm)) { 2228 case SND_SOC_BIAS_ON: 2229 state = "On"; 2230 break; 2231 case SND_SOC_BIAS_PREPARE: 2232 state = "Prepare"; 2233 break; 2234 case SND_SOC_BIAS_STANDBY: 2235 state = "Standby"; 2236 break; 2237 case SND_SOC_BIAS_OFF: 2238 state = "Off"; 2239 break; 2240 } 2241 count += sprintf(buf + count, "PM State: %s\n", state); 2242 2243 return count; 2244} 2245 2246/* show dapm widget status in sys fs */ 2247static ssize_t dapm_widget_show(struct device *dev, 2248 struct device_attribute *attr, char *buf) 2249{ 2250 struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev); 2251 int i, count = 0; 2252 2253 mutex_lock(&rtd->card->dapm_mutex); 2254 2255 for (i = 0; i < rtd->num_codecs; i++) { 2256 struct snd_soc_component *cmpnt = rtd->codec_dais[i]->component; 2257 2258 count += dapm_widget_show_component(cmpnt, buf + count); 2259 } 2260 2261 mutex_unlock(&rtd->card->dapm_mutex); 2262 2263 return count; 2264} 2265 2266static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL); 2267 2268struct attribute *soc_dapm_dev_attrs[] = { 2269 &dev_attr_dapm_widget.attr, 2270 NULL 2271}; 2272 2273static void dapm_free_path(struct snd_soc_dapm_path *path) 2274{ 2275 list_del(&path->list_node[SND_SOC_DAPM_DIR_IN]); 2276 list_del(&path->list_node[SND_SOC_DAPM_DIR_OUT]); 2277 list_del(&path->list_kcontrol); 2278 list_del(&path->list); 2279 kfree(path); 2280} 2281 2282void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w) 2283{ 2284 struct snd_soc_dapm_path *p, *next_p; 2285 enum snd_soc_dapm_direction dir; 2286 2287 list_del(&w->list); 2288 /* 2289 * remove source and sink paths associated to this widget. 2290 * While removing the path, remove reference to it from both 2291 * source and sink widgets so that path is removed only once. 2292 */ 2293 snd_soc_dapm_for_each_direction(dir) { 2294 snd_soc_dapm_widget_for_each_path_safe(w, dir, p, next_p) 2295 dapm_free_path(p); 2296 } 2297 2298 kfree(w->kcontrols); 2299 kfree_const(w->name); 2300 kfree(w); 2301} 2302 2303void snd_soc_dapm_reset_cache(struct snd_soc_dapm_context *dapm) 2304{ 2305 dapm->path_sink_cache.widget = NULL; 2306 dapm->path_source_cache.widget = NULL; 2307} 2308 2309/* free all dapm widgets and resources */ 2310static void dapm_free_widgets(struct snd_soc_dapm_context *dapm) 2311{ 2312 struct snd_soc_dapm_widget *w, *next_w; 2313 2314 list_for_each_entry_safe(w, next_w, &dapm->card->widgets, list) { 2315 if (w->dapm != dapm) 2316 continue; 2317 snd_soc_dapm_free_widget(w); 2318 } 2319 snd_soc_dapm_reset_cache(dapm); 2320} 2321 2322static struct snd_soc_dapm_widget *dapm_find_widget( 2323 struct snd_soc_dapm_context *dapm, const char *pin, 2324 bool search_other_contexts) 2325{ 2326 struct snd_soc_dapm_widget *w; 2327 struct snd_soc_dapm_widget *fallback = NULL; 2328 2329 list_for_each_entry(w, &dapm->card->widgets, list) { 2330 if (!strcmp(w->name, pin)) { 2331 if (w->dapm == dapm) 2332 return w; 2333 else 2334 fallback = w; 2335 } 2336 } 2337 2338 if (search_other_contexts) 2339 return fallback; 2340 2341 return NULL; 2342} 2343 2344static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, 2345 const char *pin, int status) 2346{ 2347 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); 2348 2349 dapm_assert_locked(dapm); 2350 2351 if (!w) { 2352 dev_err(dapm->dev, "ASoC: DAPM unknown pin %s\n", pin); 2353 return -EINVAL; 2354 } 2355 2356 if (w->connected != status) { 2357 dapm_mark_dirty(w, "pin configuration"); 2358 dapm_widget_invalidate_input_paths(w); 2359 dapm_widget_invalidate_output_paths(w); 2360 } 2361 2362 w->connected = status; 2363 if (status == 0) 2364 w->force = 0; 2365 2366 return 0; 2367} 2368 2369/** 2370 * snd_soc_dapm_sync_unlocked - scan and power dapm paths 2371 * @dapm: DAPM context 2372 * 2373 * Walks all dapm audio paths and powers widgets according to their 2374 * stream or path usage. 2375 * 2376 * Requires external locking. 2377 * 2378 * Returns 0 for success. 2379 */ 2380int snd_soc_dapm_sync_unlocked(struct snd_soc_dapm_context *dapm) 2381{ 2382 /* 2383 * Suppress early reports (eg, jacks syncing their state) to avoid 2384 * silly DAPM runs during card startup. 2385 */ 2386 if (!dapm->card || !dapm->card->instantiated) 2387 return 0; 2388 2389 return dapm_power_widgets(dapm->card, SND_SOC_DAPM_STREAM_NOP); 2390} 2391EXPORT_SYMBOL_GPL(snd_soc_dapm_sync_unlocked); 2392 2393/** 2394 * snd_soc_dapm_sync - scan and power dapm paths 2395 * @dapm: DAPM context 2396 * 2397 * Walks all dapm audio paths and powers widgets according to their 2398 * stream or path usage. 2399 * 2400 * Returns 0 for success. 2401 */ 2402int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm) 2403{ 2404 int ret; 2405 2406 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 2407 ret = snd_soc_dapm_sync_unlocked(dapm); 2408 mutex_unlock(&dapm->card->dapm_mutex); 2409 return ret; 2410} 2411EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); 2412 2413/* 2414 * dapm_update_widget_flags() - Re-compute widget sink and source flags 2415 * @w: The widget for which to update the flags 2416 * 2417 * Some widgets have a dynamic category which depends on which neighbors they 2418 * are connected to. This function update the category for these widgets. 2419 * 2420 * This function must be called whenever a path is added or removed to a widget. 2421 */ 2422static void dapm_update_widget_flags(struct snd_soc_dapm_widget *w) 2423{ 2424 enum snd_soc_dapm_direction dir; 2425 struct snd_soc_dapm_path *p; 2426 unsigned int ep; 2427 2428 switch (w->id) { 2429 case snd_soc_dapm_input: 2430 /* On a fully routed card a input is never a source */ 2431 if (w->dapm->card->fully_routed) 2432 return; 2433 ep = SND_SOC_DAPM_EP_SOURCE; 2434 snd_soc_dapm_widget_for_each_source_path(w, p) { 2435 if (p->source->id == snd_soc_dapm_micbias || 2436 p->source->id == snd_soc_dapm_mic || 2437 p->source->id == snd_soc_dapm_line || 2438 p->source->id == snd_soc_dapm_output) { 2439 ep = 0; 2440 break; 2441 } 2442 } 2443 break; 2444 case snd_soc_dapm_output: 2445 /* On a fully routed card a output is never a sink */ 2446 if (w->dapm->card->fully_routed) 2447 return; 2448 ep = SND_SOC_DAPM_EP_SINK; 2449 snd_soc_dapm_widget_for_each_sink_path(w, p) { 2450 if (p->sink->id == snd_soc_dapm_spk || 2451 p->sink->id == snd_soc_dapm_hp || 2452 p->sink->id == snd_soc_dapm_line || 2453 p->sink->id == snd_soc_dapm_input) { 2454 ep = 0; 2455 break; 2456 } 2457 } 2458 break; 2459 case snd_soc_dapm_line: 2460 ep = 0; 2461 snd_soc_dapm_for_each_direction(dir) { 2462 if (!list_empty(&w->edges[dir])) 2463 ep |= SND_SOC_DAPM_DIR_TO_EP(dir); 2464 } 2465 break; 2466 default: 2467 return; 2468 } 2469 2470 w->is_ep = ep; 2471} 2472 2473static int snd_soc_dapm_check_dynamic_path(struct snd_soc_dapm_context *dapm, 2474 struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink, 2475 const char *control) 2476{ 2477 bool dynamic_source = false; 2478 bool dynamic_sink = false; 2479 2480 if (!control) 2481 return 0; 2482 2483 switch (source->id) { 2484 case snd_soc_dapm_demux: 2485 dynamic_source = true; 2486 break; 2487 default: 2488 break; 2489 } 2490 2491 switch (sink->id) { 2492 case snd_soc_dapm_mux: 2493 case snd_soc_dapm_switch: 2494 case snd_soc_dapm_mixer: 2495 case snd_soc_dapm_mixer_named_ctl: 2496 dynamic_sink = true; 2497 break; 2498 default: 2499 break; 2500 } 2501 2502 if (dynamic_source && dynamic_sink) { 2503 dev_err(dapm->dev, 2504 "Direct connection between demux and mixer/mux not supported for path %s -> [%s] -> %s\n", 2505 source->name, control, sink->name); 2506 return -EINVAL; 2507 } else if (!dynamic_source && !dynamic_sink) { 2508 dev_err(dapm->dev, 2509 "Control not supported for path %s -> [%s] -> %s\n", 2510 source->name, control, sink->name); 2511 return -EINVAL; 2512 } 2513 2514 return 0; 2515} 2516 2517static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm, 2518 struct snd_soc_dapm_widget *wsource, struct snd_soc_dapm_widget *wsink, 2519 const char *control, 2520 int (*connected)(struct snd_soc_dapm_widget *source, 2521 struct snd_soc_dapm_widget *sink)) 2522{ 2523 struct snd_soc_dapm_widget *widgets[2]; 2524 enum snd_soc_dapm_direction dir; 2525 struct snd_soc_dapm_path *path; 2526 int ret; 2527 2528 if (wsink->is_supply && !wsource->is_supply) { 2529 dev_err(dapm->dev, 2530 "Connecting non-supply widget to supply widget is not supported (%s -> %s)\n", 2531 wsource->name, wsink->name); 2532 return -EINVAL; 2533 } 2534 2535 if (connected && !wsource->is_supply) { 2536 dev_err(dapm->dev, 2537 "connected() callback only supported for supply widgets (%s -> %s)\n", 2538 wsource->name, wsink->name); 2539 return -EINVAL; 2540 } 2541 2542 if (wsource->is_supply && control) { 2543 dev_err(dapm->dev, 2544 "Conditional paths are not supported for supply widgets (%s -> [%s] -> %s)\n", 2545 wsource->name, control, wsink->name); 2546 return -EINVAL; 2547 } 2548 2549 ret = snd_soc_dapm_check_dynamic_path(dapm, wsource, wsink, control); 2550 if (ret) 2551 return ret; 2552 2553 path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL); 2554 if (!path) 2555 return -ENOMEM; 2556 2557 path->node[SND_SOC_DAPM_DIR_IN] = wsource; 2558 path->node[SND_SOC_DAPM_DIR_OUT] = wsink; 2559 widgets[SND_SOC_DAPM_DIR_IN] = wsource; 2560 widgets[SND_SOC_DAPM_DIR_OUT] = wsink; 2561 2562 path->connected = connected; 2563 INIT_LIST_HEAD(&path->list); 2564 INIT_LIST_HEAD(&path->list_kcontrol); 2565 2566 if (wsource->is_supply || wsink->is_supply) 2567 path->is_supply = 1; 2568 2569 /* connect static paths */ 2570 if (control == NULL) { 2571 path->connect = 1; 2572 } else { 2573 switch (wsource->id) { 2574 case snd_soc_dapm_demux: 2575 ret = dapm_connect_mux(dapm, path, control, wsource); 2576 if (ret) 2577 goto err; 2578 break; 2579 default: 2580 break; 2581 } 2582 2583 switch (wsink->id) { 2584 case snd_soc_dapm_mux: 2585 ret = dapm_connect_mux(dapm, path, control, wsink); 2586 if (ret != 0) 2587 goto err; 2588 break; 2589 case snd_soc_dapm_switch: 2590 case snd_soc_dapm_mixer: 2591 case snd_soc_dapm_mixer_named_ctl: 2592 ret = dapm_connect_mixer(dapm, path, control); 2593 if (ret != 0) 2594 goto err; 2595 break; 2596 default: 2597 break; 2598 } 2599 } 2600 2601 list_add(&path->list, &dapm->card->paths); 2602 snd_soc_dapm_for_each_direction(dir) 2603 list_add(&path->list_node[dir], &widgets[dir]->edges[dir]); 2604 2605 snd_soc_dapm_for_each_direction(dir) { 2606 dapm_update_widget_flags(widgets[dir]); 2607 dapm_mark_dirty(widgets[dir], "Route added"); 2608 } 2609 2610 if (dapm->card->instantiated && path->connect) 2611 dapm_path_invalidate(path); 2612 2613 return 0; 2614err: 2615 kfree(path); 2616 return ret; 2617} 2618 2619static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, 2620 const struct snd_soc_dapm_route *route) 2621{ 2622 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; 2623 struct snd_soc_dapm_widget *wtsource = NULL, *wtsink = NULL; 2624 const char *sink; 2625 const char *source; 2626 char prefixed_sink[80]; 2627 char prefixed_source[80]; 2628 const char *prefix; 2629 int ret; 2630 2631 prefix = soc_dapm_prefix(dapm); 2632 if (prefix) { 2633 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s", 2634 prefix, route->sink); 2635 sink = prefixed_sink; 2636 snprintf(prefixed_source, sizeof(prefixed_source), "%s %s", 2637 prefix, route->source); 2638 source = prefixed_source; 2639 } else { 2640 sink = route->sink; 2641 source = route->source; 2642 } 2643 2644 wsource = dapm_wcache_lookup(&dapm->path_source_cache, source); 2645 wsink = dapm_wcache_lookup(&dapm->path_sink_cache, sink); 2646 2647 if (wsink && wsource) 2648 goto skip_search; 2649 2650 /* 2651 * find src and dest widgets over all widgets but favor a widget from 2652 * current DAPM context 2653 */ 2654 list_for_each_entry(w, &dapm->card->widgets, list) { 2655 if (!wsink && !(strcmp(w->name, sink))) { 2656 wtsink = w; 2657 if (w->dapm == dapm) { 2658 wsink = w; 2659 if (wsource) 2660 break; 2661 } 2662 continue; 2663 } 2664 if (!wsource && !(strcmp(w->name, source))) { 2665 wtsource = w; 2666 if (w->dapm == dapm) { 2667 wsource = w; 2668 if (wsink) 2669 break; 2670 } 2671 } 2672 } 2673 /* use widget from another DAPM context if not found from this */ 2674 if (!wsink) 2675 wsink = wtsink; 2676 if (!wsource) 2677 wsource = wtsource; 2678 2679 if (wsource == NULL) { 2680 dev_err(dapm->dev, "ASoC: no source widget found for %s\n", 2681 route->source); 2682 return -ENODEV; 2683 } 2684 if (wsink == NULL) { 2685 dev_err(dapm->dev, "ASoC: no sink widget found for %s\n", 2686 route->sink); 2687 return -ENODEV; 2688 } 2689 2690skip_search: 2691 dapm_wcache_update(&dapm->path_sink_cache, wsink); 2692 dapm_wcache_update(&dapm->path_source_cache, wsource); 2693 2694 ret = snd_soc_dapm_add_path(dapm, wsource, wsink, route->control, 2695 route->connected); 2696 if (ret) 2697 goto err; 2698 2699 return 0; 2700err: 2701 dev_warn(dapm->dev, "ASoC: no dapm match for %s --> %s --> %s\n", 2702 source, route->control, sink); 2703 return ret; 2704} 2705 2706static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm, 2707 const struct snd_soc_dapm_route *route) 2708{ 2709 struct snd_soc_dapm_widget *wsource, *wsink; 2710 struct snd_soc_dapm_path *path, *p; 2711 const char *sink; 2712 const char *source; 2713 char prefixed_sink[80]; 2714 char prefixed_source[80]; 2715 const char *prefix; 2716 2717 if (route->control) { 2718 dev_err(dapm->dev, 2719 "ASoC: Removal of routes with controls not supported\n"); 2720 return -EINVAL; 2721 } 2722 2723 prefix = soc_dapm_prefix(dapm); 2724 if (prefix) { 2725 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s", 2726 prefix, route->sink); 2727 sink = prefixed_sink; 2728 snprintf(prefixed_source, sizeof(prefixed_source), "%s %s", 2729 prefix, route->source); 2730 source = prefixed_source; 2731 } else { 2732 sink = route->sink; 2733 source = route->source; 2734 } 2735 2736 path = NULL; 2737 list_for_each_entry(p, &dapm->card->paths, list) { 2738 if (strcmp(p->source->name, source) != 0) 2739 continue; 2740 if (strcmp(p->sink->name, sink) != 0) 2741 continue; 2742 path = p; 2743 break; 2744 } 2745 2746 if (path) { 2747 wsource = path->source; 2748 wsink = path->sink; 2749 2750 dapm_mark_dirty(wsource, "Route removed"); 2751 dapm_mark_dirty(wsink, "Route removed"); 2752 if (path->connect) 2753 dapm_path_invalidate(path); 2754 2755 dapm_free_path(path); 2756 2757 /* Update any path related flags */ 2758 dapm_update_widget_flags(wsource); 2759 dapm_update_widget_flags(wsink); 2760 } else { 2761 dev_warn(dapm->dev, "ASoC: Route %s->%s does not exist\n", 2762 source, sink); 2763 } 2764 2765 return 0; 2766} 2767 2768/** 2769 * snd_soc_dapm_add_routes - Add routes between DAPM widgets 2770 * @dapm: DAPM context 2771 * @route: audio routes 2772 * @num: number of routes 2773 * 2774 * Connects 2 dapm widgets together via a named audio path. The sink is 2775 * the widget receiving the audio signal, whilst the source is the sender 2776 * of the audio signal. 2777 * 2778 * Returns 0 for success else error. On error all resources can be freed 2779 * with a call to snd_soc_card_free(). 2780 */ 2781int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, 2782 const struct snd_soc_dapm_route *route, int num) 2783{ 2784 int i, r, ret = 0; 2785 2786 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); 2787 for (i = 0; i < num; i++) { 2788 r = snd_soc_dapm_add_route(dapm, route); 2789 if (r < 0) { 2790 dev_err(dapm->dev, "ASoC: Failed to add route %s -> %s -> %s\n", 2791 route->source, 2792 route->control ? route->control : "direct", 2793 route->sink); 2794 ret = r; 2795 } 2796 route++; 2797 } 2798 mutex_unlock(&dapm->card->dapm_mutex); 2799 2800 return ret; 2801} 2802EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes); 2803 2804/** 2805 * snd_soc_dapm_del_routes - Remove routes between DAPM widgets 2806 * @dapm: DAPM context 2807 * @route: audio routes 2808 * @num: number of routes 2809 * 2810 * Removes routes from the DAPM context. 2811 */ 2812int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm, 2813 const struct snd_soc_dapm_route *route, int num) 2814{ 2815 int i, ret = 0; 2816 2817 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); 2818 for (i = 0; i < num; i++) { 2819 snd_soc_dapm_del_route(dapm, route); 2820 route++; 2821 } 2822 mutex_unlock(&dapm->card->dapm_mutex); 2823 2824 return ret; 2825} 2826EXPORT_SYMBOL_GPL(snd_soc_dapm_del_routes); 2827 2828static int snd_soc_dapm_weak_route(struct snd_soc_dapm_context *dapm, 2829 const struct snd_soc_dapm_route *route) 2830{ 2831 struct snd_soc_dapm_widget *source = dapm_find_widget(dapm, 2832 route->source, 2833 true); 2834 struct snd_soc_dapm_widget *sink = dapm_find_widget(dapm, 2835 route->sink, 2836 true); 2837 struct snd_soc_dapm_path *path; 2838 int count = 0; 2839 2840 if (!source) { 2841 dev_err(dapm->dev, "ASoC: Unable to find source %s for weak route\n", 2842 route->source); 2843 return -ENODEV; 2844 } 2845 2846 if (!sink) { 2847 dev_err(dapm->dev, "ASoC: Unable to find sink %s for weak route\n", 2848 route->sink); 2849 return -ENODEV; 2850 } 2851 2852 if (route->control || route->connected) 2853 dev_warn(dapm->dev, "ASoC: Ignoring control for weak route %s->%s\n", 2854 route->source, route->sink); 2855 2856 snd_soc_dapm_widget_for_each_sink_path(source, path) { 2857 if (path->sink == sink) { 2858 path->weak = 1; 2859 count++; 2860 } 2861 } 2862 2863 if (count == 0) 2864 dev_err(dapm->dev, "ASoC: No path found for weak route %s->%s\n", 2865 route->source, route->sink); 2866 if (count > 1) 2867 dev_warn(dapm->dev, "ASoC: %d paths found for weak route %s->%s\n", 2868 count, route->source, route->sink); 2869 2870 return 0; 2871} 2872 2873/** 2874 * snd_soc_dapm_weak_routes - Mark routes between DAPM widgets as weak 2875 * @dapm: DAPM context 2876 * @route: audio routes 2877 * @num: number of routes 2878 * 2879 * Mark existing routes matching those specified in the passed array 2880 * as being weak, meaning that they are ignored for the purpose of 2881 * power decisions. The main intended use case is for sidetone paths 2882 * which couple audio between other independent paths if they are both 2883 * active in order to make the combination work better at the user 2884 * level but which aren't intended to be "used". 2885 * 2886 * Note that CODEC drivers should not use this as sidetone type paths 2887 * can frequently also be used as bypass paths. 2888 */ 2889int snd_soc_dapm_weak_routes(struct snd_soc_dapm_context *dapm, 2890 const struct snd_soc_dapm_route *route, int num) 2891{ 2892 int i, err; 2893 int ret = 0; 2894 2895 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); 2896 for (i = 0; i < num; i++) { 2897 err = snd_soc_dapm_weak_route(dapm, route); 2898 if (err) 2899 ret = err; 2900 route++; 2901 } 2902 mutex_unlock(&dapm->card->dapm_mutex); 2903 2904 return ret; 2905} 2906EXPORT_SYMBOL_GPL(snd_soc_dapm_weak_routes); 2907 2908/** 2909 * snd_soc_dapm_new_widgets - add new dapm widgets 2910 * @card: card to be checked for new dapm widgets 2911 * 2912 * Checks the codec for any new dapm widgets and creates them if found. 2913 * 2914 * Returns 0 for success. 2915 */ 2916int snd_soc_dapm_new_widgets(struct snd_soc_card *card) 2917{ 2918 struct snd_soc_dapm_widget *w; 2919 unsigned int val; 2920 2921 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); 2922 2923 list_for_each_entry(w, &card->widgets, list) 2924 { 2925 if (w->new) 2926 continue; 2927 2928 if (w->num_kcontrols) { 2929 w->kcontrols = kzalloc(w->num_kcontrols * 2930 sizeof(struct snd_kcontrol *), 2931 GFP_KERNEL); 2932 if (!w->kcontrols) { 2933 mutex_unlock(&card->dapm_mutex); 2934 return -ENOMEM; 2935 } 2936 } 2937 2938 switch(w->id) { 2939 case snd_soc_dapm_switch: 2940 case snd_soc_dapm_mixer: 2941 case snd_soc_dapm_mixer_named_ctl: 2942 dapm_new_mixer(w); 2943 break; 2944 case snd_soc_dapm_mux: 2945 case snd_soc_dapm_demux: 2946 dapm_new_mux(w); 2947 break; 2948 case snd_soc_dapm_pga: 2949 case snd_soc_dapm_out_drv: 2950 dapm_new_pga(w); 2951 break; 2952 case snd_soc_dapm_dai_link: 2953 dapm_new_dai_link(w); 2954 break; 2955 default: 2956 break; 2957 } 2958 2959 /* Read the initial power state from the device */ 2960 if (w->reg >= 0) { 2961 soc_dapm_read(w->dapm, w->reg, &val); 2962 val = val >> w->shift; 2963 val &= w->mask; 2964 if (val == w->on_val) 2965 w->power = 1; 2966 } 2967 2968 w->new = 1; 2969 2970 dapm_mark_dirty(w, "new widget"); 2971 dapm_debugfs_add_widget(w); 2972 } 2973 2974 dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP); 2975 mutex_unlock(&card->dapm_mutex); 2976 return 0; 2977} 2978EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets); 2979 2980/** 2981 * snd_soc_dapm_get_volsw - dapm mixer get callback 2982 * @kcontrol: mixer control 2983 * @ucontrol: control element information 2984 * 2985 * Callback to get the value of a dapm mixer control. 2986 * 2987 * Returns 0 for success. 2988 */ 2989int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, 2990 struct snd_ctl_elem_value *ucontrol) 2991{ 2992 struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); 2993 struct snd_soc_card *card = dapm->card; 2994 struct soc_mixer_control *mc = 2995 (struct soc_mixer_control *)kcontrol->private_value; 2996 int reg = mc->reg; 2997 unsigned int shift = mc->shift; 2998 int max = mc->max; 2999 unsigned int mask = (1 << fls(max)) - 1; 3000 unsigned int invert = mc->invert; 3001 unsigned int val; 3002 int ret = 0; 3003 3004 if (snd_soc_volsw_is_stereo(mc)) 3005 dev_warn(dapm->dev, 3006 "ASoC: Control '%s' is stereo, which is not supported\n", 3007 kcontrol->id.name); 3008 3009 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 3010 if (dapm_kcontrol_is_powered(kcontrol) && reg != SND_SOC_NOPM) { 3011 ret = soc_dapm_read(dapm, reg, &val); 3012 val = (val >> shift) & mask; 3013 } else { 3014 val = dapm_kcontrol_get_value(kcontrol); 3015 } 3016 mutex_unlock(&card->dapm_mutex); 3017 3018 if (invert) 3019 ucontrol->value.integer.value[0] = max - val; 3020 else 3021 ucontrol->value.integer.value[0] = val; 3022 3023 return ret; 3024} 3025EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw); 3026 3027/** 3028 * snd_soc_dapm_put_volsw - dapm mixer set callback 3029 * @kcontrol: mixer control 3030 * @ucontrol: control element information 3031 * 3032 * Callback to set the value of a dapm mixer control. 3033 * 3034 * Returns 0 for success. 3035 */ 3036int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, 3037 struct snd_ctl_elem_value *ucontrol) 3038{ 3039 struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); 3040 struct snd_soc_card *card = dapm->card; 3041 struct soc_mixer_control *mc = 3042 (struct soc_mixer_control *)kcontrol->private_value; 3043 int reg = mc->reg; 3044 unsigned int shift = mc->shift; 3045 int max = mc->max; 3046 unsigned int mask = (1 << fls(max)) - 1; 3047 unsigned int invert = mc->invert; 3048 unsigned int val; 3049 int connect, change, reg_change = 0; 3050 struct snd_soc_dapm_update update; 3051 int ret = 0; 3052 3053 if (snd_soc_volsw_is_stereo(mc)) 3054 dev_warn(dapm->dev, 3055 "ASoC: Control '%s' is stereo, which is not supported\n", 3056 kcontrol->id.name); 3057 3058 val = (ucontrol->value.integer.value[0] & mask); 3059 connect = !!val; 3060 3061 if (invert) 3062 val = max - val; 3063 3064 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 3065 3066 change = dapm_kcontrol_set_value(kcontrol, val); 3067 3068 if (reg != SND_SOC_NOPM) { 3069 mask = mask << shift; 3070 val = val << shift; 3071 3072 reg_change = soc_dapm_test_bits(dapm, reg, mask, val); 3073 } 3074 3075 if (change || reg_change) { 3076 if (reg_change) { 3077 update.kcontrol = kcontrol; 3078 update.reg = reg; 3079 update.mask = mask; 3080 update.val = val; 3081 card->update = &update; 3082 } 3083 change |= reg_change; 3084 3085 ret = soc_dapm_mixer_update_power(card, kcontrol, connect); 3086 3087 card->update = NULL; 3088 } 3089 3090 mutex_unlock(&card->dapm_mutex); 3091 3092 if (ret > 0) 3093 soc_dpcm_runtime_update(card); 3094 3095 return change; 3096} 3097EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw); 3098 3099/** 3100 * snd_soc_dapm_get_enum_double - dapm enumerated double mixer get callback 3101 * @kcontrol: mixer control 3102 * @ucontrol: control element information 3103 * 3104 * Callback to get the value of a dapm enumerated double mixer control. 3105 * 3106 * Returns 0 for success. 3107 */ 3108int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol, 3109 struct snd_ctl_elem_value *ucontrol) 3110{ 3111 struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); 3112 struct snd_soc_card *card = dapm->card; 3113 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 3114 unsigned int reg_val, val; 3115 3116 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 3117 if (e->reg != SND_SOC_NOPM && dapm_kcontrol_is_powered(kcontrol)) { 3118 int ret = soc_dapm_read(dapm, e->reg, ®_val); 3119 if (ret) { 3120 mutex_unlock(&card->dapm_mutex); 3121 return ret; 3122 } 3123 } else { 3124 reg_val = dapm_kcontrol_get_value(kcontrol); 3125 } 3126 mutex_unlock(&card->dapm_mutex); 3127 3128 val = (reg_val >> e->shift_l) & e->mask; 3129 ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(e, val); 3130 if (e->shift_l != e->shift_r) { 3131 val = (reg_val >> e->shift_r) & e->mask; 3132 val = snd_soc_enum_val_to_item(e, val); 3133 ucontrol->value.enumerated.item[1] = val; 3134 } 3135 3136 return 0; 3137} 3138EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double); 3139 3140/** 3141 * snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback 3142 * @kcontrol: mixer control 3143 * @ucontrol: control element information 3144 * 3145 * Callback to set the value of a dapm enumerated double mixer control. 3146 * 3147 * Returns 0 for success. 3148 */ 3149int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, 3150 struct snd_ctl_elem_value *ucontrol) 3151{ 3152 struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); 3153 struct snd_soc_card *card = dapm->card; 3154 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 3155 unsigned int *item = ucontrol->value.enumerated.item; 3156 unsigned int val, change, reg_change = 0; 3157 unsigned int mask; 3158 struct snd_soc_dapm_update update; 3159 int ret = 0; 3160 3161 if (item[0] >= e->items) 3162 return -EINVAL; 3163 3164 val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l; 3165 mask = e->mask << e->shift_l; 3166 if (e->shift_l != e->shift_r) { 3167 if (item[1] > e->items) 3168 return -EINVAL; 3169 val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_l; 3170 mask |= e->mask << e->shift_r; 3171 } 3172 3173 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 3174 3175 change = dapm_kcontrol_set_value(kcontrol, val); 3176 3177 if (e->reg != SND_SOC_NOPM) 3178 reg_change = soc_dapm_test_bits(dapm, e->reg, mask, val); 3179 3180 if (change || reg_change) { 3181 if (reg_change) { 3182 update.kcontrol = kcontrol; 3183 update.reg = e->reg; 3184 update.mask = mask; 3185 update.val = val; 3186 card->update = &update; 3187 } 3188 change |= reg_change; 3189 3190 ret = soc_dapm_mux_update_power(card, kcontrol, item[0], e); 3191 3192 card->update = NULL; 3193 } 3194 3195 mutex_unlock(&card->dapm_mutex); 3196 3197 if (ret > 0) 3198 soc_dpcm_runtime_update(card); 3199 3200 return change; 3201} 3202EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double); 3203 3204/** 3205 * snd_soc_dapm_info_pin_switch - Info for a pin switch 3206 * 3207 * @kcontrol: mixer control 3208 * @uinfo: control element information 3209 * 3210 * Callback to provide information about a pin switch control. 3211 */ 3212int snd_soc_dapm_info_pin_switch(struct snd_kcontrol *kcontrol, 3213 struct snd_ctl_elem_info *uinfo) 3214{ 3215 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 3216 uinfo->count = 1; 3217 uinfo->value.integer.min = 0; 3218 uinfo->value.integer.max = 1; 3219 3220 return 0; 3221} 3222EXPORT_SYMBOL_GPL(snd_soc_dapm_info_pin_switch); 3223 3224/** 3225 * snd_soc_dapm_get_pin_switch - Get information for a pin switch 3226 * 3227 * @kcontrol: mixer control 3228 * @ucontrol: Value 3229 */ 3230int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol, 3231 struct snd_ctl_elem_value *ucontrol) 3232{ 3233 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); 3234 const char *pin = (const char *)kcontrol->private_value; 3235 3236 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 3237 3238 ucontrol->value.integer.value[0] = 3239 snd_soc_dapm_get_pin_status(&card->dapm, pin); 3240 3241 mutex_unlock(&card->dapm_mutex); 3242 3243 return 0; 3244} 3245EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_switch); 3246 3247/** 3248 * snd_soc_dapm_put_pin_switch - Set information for a pin switch 3249 * 3250 * @kcontrol: mixer control 3251 * @ucontrol: Value 3252 */ 3253int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, 3254 struct snd_ctl_elem_value *ucontrol) 3255{ 3256 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); 3257 const char *pin = (const char *)kcontrol->private_value; 3258 3259 if (ucontrol->value.integer.value[0]) 3260 snd_soc_dapm_enable_pin(&card->dapm, pin); 3261 else 3262 snd_soc_dapm_disable_pin(&card->dapm, pin); 3263 3264 snd_soc_dapm_sync(&card->dapm); 3265 return 0; 3266} 3267EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch); 3268 3269struct snd_soc_dapm_widget * 3270snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, 3271 const struct snd_soc_dapm_widget *widget) 3272{ 3273 struct snd_soc_dapm_widget *w; 3274 3275 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 3276 w = snd_soc_dapm_new_control_unlocked(dapm, widget); 3277 if (!w) 3278 dev_err(dapm->dev, 3279 "ASoC: Failed to create DAPM control %s\n", 3280 widget->name); 3281 3282 mutex_unlock(&dapm->card->dapm_mutex); 3283 return w; 3284} 3285 3286struct snd_soc_dapm_widget * 3287snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm, 3288 const struct snd_soc_dapm_widget *widget) 3289{ 3290 enum snd_soc_dapm_direction dir; 3291 struct snd_soc_dapm_widget *w; 3292 const char *prefix; 3293 int ret; 3294 3295 if ((w = dapm_cnew_widget(widget)) == NULL) 3296 return NULL; 3297 3298 switch (w->id) { 3299 case snd_soc_dapm_regulator_supply: 3300 w->regulator = devm_regulator_get(dapm->dev, w->name); 3301 if (IS_ERR(w->regulator)) { 3302 ret = PTR_ERR(w->regulator); 3303 dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n", 3304 w->name, ret); 3305 return NULL; 3306 } 3307 3308 if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) { 3309 ret = regulator_allow_bypass(w->regulator, true); 3310 if (ret != 0) 3311 dev_warn(w->dapm->dev, 3312 "ASoC: Failed to bypass %s: %d\n", 3313 w->name, ret); 3314 } 3315 break; 3316 case snd_soc_dapm_clock_supply: 3317#ifdef CONFIG_CLKDEV_LOOKUP 3318 w->clk = devm_clk_get(dapm->dev, w->name); 3319 if (IS_ERR(w->clk)) { 3320 ret = PTR_ERR(w->clk); 3321 dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n", 3322 w->name, ret); 3323 return NULL; 3324 } 3325#else 3326 return NULL; 3327#endif 3328 break; 3329 default: 3330 break; 3331 } 3332 3333 prefix = soc_dapm_prefix(dapm); 3334 if (prefix) 3335 w->name = kasprintf(GFP_KERNEL, "%s %s", prefix, widget->name); 3336 else 3337 w->name = kstrdup_const(widget->name, GFP_KERNEL); 3338 if (w->name == NULL) { 3339 kfree(w); 3340 return NULL; 3341 } 3342 3343 switch (w->id) { 3344 case snd_soc_dapm_mic: 3345 w->is_ep = SND_SOC_DAPM_EP_SOURCE; 3346 w->power_check = dapm_generic_check_power; 3347 break; 3348 case snd_soc_dapm_input: 3349 if (!dapm->card->fully_routed) 3350 w->is_ep = SND_SOC_DAPM_EP_SOURCE; 3351 w->power_check = dapm_generic_check_power; 3352 break; 3353 case snd_soc_dapm_spk: 3354 case snd_soc_dapm_hp: 3355 w->is_ep = SND_SOC_DAPM_EP_SINK; 3356 w->power_check = dapm_generic_check_power; 3357 break; 3358 case snd_soc_dapm_output: 3359 if (!dapm->card->fully_routed) 3360 w->is_ep = SND_SOC_DAPM_EP_SINK; 3361 w->power_check = dapm_generic_check_power; 3362 break; 3363 case snd_soc_dapm_vmid: 3364 case snd_soc_dapm_siggen: 3365 w->is_ep = SND_SOC_DAPM_EP_SOURCE; 3366 w->power_check = dapm_always_on_check_power; 3367 break; 3368 case snd_soc_dapm_mux: 3369 case snd_soc_dapm_demux: 3370 case snd_soc_dapm_switch: 3371 case snd_soc_dapm_mixer: 3372 case snd_soc_dapm_mixer_named_ctl: 3373 case snd_soc_dapm_adc: 3374 case snd_soc_dapm_aif_out: 3375 case snd_soc_dapm_dac: 3376 case snd_soc_dapm_aif_in: 3377 case snd_soc_dapm_pga: 3378 case snd_soc_dapm_out_drv: 3379 case snd_soc_dapm_micbias: 3380 case snd_soc_dapm_line: 3381 case snd_soc_dapm_dai_link: 3382 case snd_soc_dapm_dai_out: 3383 case snd_soc_dapm_dai_in: 3384 w->power_check = dapm_generic_check_power; 3385 break; 3386 case snd_soc_dapm_supply: 3387 case snd_soc_dapm_regulator_supply: 3388 case snd_soc_dapm_clock_supply: 3389 case snd_soc_dapm_kcontrol: 3390 w->is_supply = 1; 3391 w->power_check = dapm_supply_check_power; 3392 break; 3393 default: 3394 w->power_check = dapm_always_on_check_power; 3395 break; 3396 } 3397 3398 w->dapm = dapm; 3399 INIT_LIST_HEAD(&w->list); 3400 INIT_LIST_HEAD(&w->dirty); 3401 list_add_tail(&w->list, &dapm->card->widgets); 3402 3403 snd_soc_dapm_for_each_direction(dir) { 3404 INIT_LIST_HEAD(&w->edges[dir]); 3405 w->endpoints[dir] = -1; 3406 } 3407 3408 /* machine layer set ups unconnected pins and insertions */ 3409 w->connected = 1; 3410 return w; 3411} 3412 3413/** 3414 * snd_soc_dapm_new_controls - create new dapm controls 3415 * @dapm: DAPM context 3416 * @widget: widget array 3417 * @num: number of widgets 3418 * 3419 * Creates new DAPM controls based upon the templates. 3420 * 3421 * Returns 0 for success else error. 3422 */ 3423int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm, 3424 const struct snd_soc_dapm_widget *widget, 3425 int num) 3426{ 3427 struct snd_soc_dapm_widget *w; 3428 int i; 3429 int ret = 0; 3430 3431 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); 3432 for (i = 0; i < num; i++) { 3433 w = snd_soc_dapm_new_control_unlocked(dapm, widget); 3434 if (!w) { 3435 dev_err(dapm->dev, 3436 "ASoC: Failed to create DAPM control %s\n", 3437 widget->name); 3438 ret = -ENOMEM; 3439 break; 3440 } 3441 widget++; 3442 } 3443 mutex_unlock(&dapm->card->dapm_mutex); 3444 return ret; 3445} 3446EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls); 3447 3448static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, 3449 struct snd_kcontrol *kcontrol, int event) 3450{ 3451 struct snd_soc_dapm_path *source_p, *sink_p; 3452 struct snd_soc_dai *source, *sink; 3453 const struct snd_soc_pcm_stream *config = w->params + w->params_select; 3454 struct snd_pcm_substream substream; 3455 struct snd_pcm_hw_params *params = NULL; 3456 u64 fmt; 3457 int ret; 3458 3459 if (WARN_ON(!config) || 3460 WARN_ON(list_empty(&w->edges[SND_SOC_DAPM_DIR_OUT]) || 3461 list_empty(&w->edges[SND_SOC_DAPM_DIR_IN]))) 3462 return -EINVAL; 3463 3464 /* We only support a single source and sink, pick the first */ 3465 source_p = list_first_entry(&w->edges[SND_SOC_DAPM_DIR_OUT], 3466 struct snd_soc_dapm_path, 3467 list_node[SND_SOC_DAPM_DIR_OUT]); 3468 sink_p = list_first_entry(&w->edges[SND_SOC_DAPM_DIR_IN], 3469 struct snd_soc_dapm_path, 3470 list_node[SND_SOC_DAPM_DIR_IN]); 3471 3472 source = source_p->source->priv; 3473 sink = sink_p->sink->priv; 3474 3475 /* Be a little careful as we don't want to overflow the mask array */ 3476 if (config->formats) { 3477 fmt = ffs(config->formats) - 1; 3478 } else { 3479 dev_warn(w->dapm->dev, "ASoC: Invalid format %llx specified\n", 3480 config->formats); 3481 fmt = 0; 3482 } 3483 3484 /* Currently very limited parameter selection */ 3485 params = kzalloc(sizeof(*params), GFP_KERNEL); 3486 if (!params) { 3487 ret = -ENOMEM; 3488 goto out; 3489 } 3490 snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), fmt); 3491 3492 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min = 3493 config->rate_min; 3494 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max = 3495 config->rate_max; 3496 3497 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min 3498 = config->channels_min; 3499 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max 3500 = config->channels_max; 3501 3502 memset(&substream, 0, sizeof(substream)); 3503 3504 switch (event) { 3505 case SND_SOC_DAPM_PRE_PMU: 3506 substream.stream = SNDRV_PCM_STREAM_CAPTURE; 3507 if (source->driver->ops && source->driver->ops->startup) { 3508 ret = source->driver->ops->startup(&substream, source); 3509 if (ret < 0) { 3510 dev_err(source->dev, 3511 "ASoC: startup() failed: %d\n", ret); 3512 goto out; 3513 } 3514 source->active++; 3515 } 3516 ret = soc_dai_hw_params(&substream, params, source); 3517 if (ret < 0) 3518 goto out; 3519 3520 substream.stream = SNDRV_PCM_STREAM_PLAYBACK; 3521 if (sink->driver->ops && sink->driver->ops->startup) { 3522 ret = sink->driver->ops->startup(&substream, sink); 3523 if (ret < 0) { 3524 dev_err(sink->dev, 3525 "ASoC: startup() failed: %d\n", ret); 3526 goto out; 3527 } 3528 sink->active++; 3529 } 3530 ret = soc_dai_hw_params(&substream, params, sink); 3531 if (ret < 0) 3532 goto out; 3533 break; 3534 3535 case SND_SOC_DAPM_POST_PMU: 3536 ret = snd_soc_dai_digital_mute(sink, 0, 3537 SNDRV_PCM_STREAM_PLAYBACK); 3538 if (ret != 0 && ret != -ENOTSUPP) 3539 dev_warn(sink->dev, "ASoC: Failed to unmute: %d\n", ret); 3540 ret = 0; 3541 break; 3542 3543 case SND_SOC_DAPM_PRE_PMD: 3544 ret = snd_soc_dai_digital_mute(sink, 1, 3545 SNDRV_PCM_STREAM_PLAYBACK); 3546 if (ret != 0 && ret != -ENOTSUPP) 3547 dev_warn(sink->dev, "ASoC: Failed to mute: %d\n", ret); 3548 ret = 0; 3549 3550 source->active--; 3551 if (source->driver->ops && source->driver->ops->shutdown) { 3552 substream.stream = SNDRV_PCM_STREAM_CAPTURE; 3553 source->driver->ops->shutdown(&substream, source); 3554 } 3555 3556 sink->active--; 3557 if (sink->driver->ops && sink->driver->ops->shutdown) { 3558 substream.stream = SNDRV_PCM_STREAM_PLAYBACK; 3559 sink->driver->ops->shutdown(&substream, sink); 3560 } 3561 break; 3562 3563 default: 3564 WARN(1, "Unknown event %d\n", event); 3565 ret = -EINVAL; 3566 } 3567 3568out: 3569 kfree(params); 3570 return ret; 3571} 3572 3573static int snd_soc_dapm_dai_link_get(struct snd_kcontrol *kcontrol, 3574 struct snd_ctl_elem_value *ucontrol) 3575{ 3576 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol); 3577 3578 ucontrol->value.enumerated.item[0] = w->params_select; 3579 3580 return 0; 3581} 3582 3583static int snd_soc_dapm_dai_link_put(struct snd_kcontrol *kcontrol, 3584 struct snd_ctl_elem_value *ucontrol) 3585{ 3586 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol); 3587 3588 /* Can't change the config when widget is already powered */ 3589 if (w->power) 3590 return -EBUSY; 3591 3592 if (ucontrol->value.enumerated.item[0] == w->params_select) 3593 return 0; 3594 3595 if (ucontrol->value.enumerated.item[0] >= w->num_params) 3596 return -EINVAL; 3597 3598 w->params_select = ucontrol->value.enumerated.item[0]; 3599 3600 return 0; 3601} 3602 3603int snd_soc_dapm_new_pcm(struct snd_soc_card *card, 3604 const struct snd_soc_pcm_stream *params, 3605 unsigned int num_params, 3606 struct snd_soc_dapm_widget *source, 3607 struct snd_soc_dapm_widget *sink) 3608{ 3609 struct snd_soc_dapm_widget template; 3610 struct snd_soc_dapm_widget *w; 3611 char *link_name; 3612 int ret, count; 3613 unsigned long private_value; 3614 const char **w_param_text; 3615 struct soc_enum w_param_enum[] = { 3616 SOC_ENUM_SINGLE(0, 0, 0, NULL), 3617 }; 3618 struct snd_kcontrol_new kcontrol_dai_link[] = { 3619 SOC_ENUM_EXT(NULL, w_param_enum[0], 3620 snd_soc_dapm_dai_link_get, 3621 snd_soc_dapm_dai_link_put), 3622 }; 3623 const struct snd_soc_pcm_stream *config = params; 3624 3625 w_param_text = devm_kcalloc(card->dev, num_params, 3626 sizeof(char *), GFP_KERNEL); 3627 if (!w_param_text) 3628 return -ENOMEM; 3629 3630 link_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s-%s", 3631 source->name, sink->name); 3632 if (!link_name) { 3633 ret = -ENOMEM; 3634 goto outfree_w_param; 3635 } 3636 3637 for (count = 0 ; count < num_params; count++) { 3638 if (!config->stream_name) { 3639 dev_warn(card->dapm.dev, 3640 "ASoC: anonymous config %d for dai link %s\n", 3641 count, link_name); 3642 w_param_text[count] = 3643 devm_kasprintf(card->dev, GFP_KERNEL, 3644 "Anonymous Configuration %d", 3645 count); 3646 if (!w_param_text[count]) { 3647 ret = -ENOMEM; 3648 goto outfree_link_name; 3649 } 3650 } else { 3651 w_param_text[count] = devm_kmemdup(card->dev, 3652 config->stream_name, 3653 strlen(config->stream_name) + 1, 3654 GFP_KERNEL); 3655 if (!w_param_text[count]) { 3656 ret = -ENOMEM; 3657 goto outfree_link_name; 3658 } 3659 } 3660 config++; 3661 } 3662 w_param_enum[0].items = num_params; 3663 w_param_enum[0].texts = w_param_text; 3664 3665 memset(&template, 0, sizeof(template)); 3666 template.reg = SND_SOC_NOPM; 3667 template.id = snd_soc_dapm_dai_link; 3668 template.name = link_name; 3669 template.event = snd_soc_dai_link_event; 3670 template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 3671 SND_SOC_DAPM_PRE_PMD; 3672 template.num_kcontrols = 1; 3673 /* duplicate w_param_enum on heap so that memory persists */ 3674 private_value = 3675 (unsigned long) devm_kmemdup(card->dev, 3676 (void *)(kcontrol_dai_link[0].private_value), 3677 sizeof(struct soc_enum), GFP_KERNEL); 3678 if (!private_value) { 3679 dev_err(card->dev, "ASoC: Failed to create control for %s widget\n", 3680 link_name); 3681 ret = -ENOMEM; 3682 goto outfree_link_name; 3683 } 3684 kcontrol_dai_link[0].private_value = private_value; 3685 /* duplicate kcontrol_dai_link on heap so that memory persists */ 3686 template.kcontrol_news = 3687 devm_kmemdup(card->dev, &kcontrol_dai_link[0], 3688 sizeof(struct snd_kcontrol_new), 3689 GFP_KERNEL); 3690 if (!template.kcontrol_news) { 3691 dev_err(card->dev, "ASoC: Failed to create control for %s widget\n", 3692 link_name); 3693 ret = -ENOMEM; 3694 goto outfree_private_value; 3695 } 3696 3697 dev_dbg(card->dev, "ASoC: adding %s widget\n", link_name); 3698 3699 w = snd_soc_dapm_new_control_unlocked(&card->dapm, &template); 3700 if (!w) { 3701 dev_err(card->dev, "ASoC: Failed to create %s widget\n", 3702 link_name); 3703 ret = -ENOMEM; 3704 goto outfree_kcontrol_news; 3705 } 3706 3707 w->params = params; 3708 w->num_params = num_params; 3709 3710 ret = snd_soc_dapm_add_path(&card->dapm, source, w, NULL, NULL); 3711 if (ret) 3712 goto outfree_w; 3713 return snd_soc_dapm_add_path(&card->dapm, w, sink, NULL, NULL); 3714 3715outfree_w: 3716 devm_kfree(card->dev, w); 3717outfree_kcontrol_news: 3718 devm_kfree(card->dev, (void *)template.kcontrol_news); 3719outfree_private_value: 3720 devm_kfree(card->dev, (void *)private_value); 3721outfree_link_name: 3722 devm_kfree(card->dev, link_name); 3723outfree_w_param: 3724 for (count = 0 ; count < num_params; count++) 3725 devm_kfree(card->dev, (void *)w_param_text[count]); 3726 devm_kfree(card->dev, w_param_text); 3727 3728 return ret; 3729} 3730 3731int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, 3732 struct snd_soc_dai *dai) 3733{ 3734 struct snd_soc_dapm_widget template; 3735 struct snd_soc_dapm_widget *w; 3736 3737 WARN_ON(dapm->dev != dai->dev); 3738 3739 memset(&template, 0, sizeof(template)); 3740 template.reg = SND_SOC_NOPM; 3741 3742 if (dai->driver->playback.stream_name) { 3743 template.id = snd_soc_dapm_dai_in; 3744 template.name = dai->driver->playback.stream_name; 3745 template.sname = dai->driver->playback.stream_name; 3746 3747 dev_dbg(dai->dev, "ASoC: adding %s widget\n", 3748 template.name); 3749 3750 w = snd_soc_dapm_new_control_unlocked(dapm, &template); 3751 if (!w) { 3752 dev_err(dapm->dev, "ASoC: Failed to create %s widget\n", 3753 dai->driver->playback.stream_name); 3754 return -ENOMEM; 3755 } 3756 3757 w->priv = dai; 3758 dai->playback_widget = w; 3759 } 3760 3761 if (dai->driver->capture.stream_name) { 3762 template.id = snd_soc_dapm_dai_out; 3763 template.name = dai->driver->capture.stream_name; 3764 template.sname = dai->driver->capture.stream_name; 3765 3766 dev_dbg(dai->dev, "ASoC: adding %s widget\n", 3767 template.name); 3768 3769 w = snd_soc_dapm_new_control_unlocked(dapm, &template); 3770 if (!w) { 3771 dev_err(dapm->dev, "ASoC: Failed to create %s widget\n", 3772 dai->driver->capture.stream_name); 3773 return -ENOMEM; 3774 } 3775 3776 w->priv = dai; 3777 dai->capture_widget = w; 3778 } 3779 3780 return 0; 3781} 3782 3783int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card) 3784{ 3785 struct snd_soc_dapm_widget *dai_w, *w; 3786 struct snd_soc_dapm_widget *src, *sink; 3787 struct snd_soc_dai *dai; 3788 3789 /* For each DAI widget... */ 3790 list_for_each_entry(dai_w, &card->widgets, list) { 3791 switch (dai_w->id) { 3792 case snd_soc_dapm_dai_in: 3793 case snd_soc_dapm_dai_out: 3794 break; 3795 default: 3796 continue; 3797 } 3798 3799 dai = dai_w->priv; 3800 3801 /* ...find all widgets with the same stream and link them */ 3802 list_for_each_entry(w, &card->widgets, list) { 3803 if (w->dapm != dai_w->dapm) 3804 continue; 3805 3806 switch (w->id) { 3807 case snd_soc_dapm_dai_in: 3808 case snd_soc_dapm_dai_out: 3809 continue; 3810 default: 3811 break; 3812 } 3813 3814 if (!w->sname || !strstr(w->sname, dai_w->sname)) 3815 continue; 3816 3817 if (dai_w->id == snd_soc_dapm_dai_in) { 3818 src = dai_w; 3819 sink = w; 3820 } else { 3821 src = w; 3822 sink = dai_w; 3823 } 3824 dev_dbg(dai->dev, "%s -> %s\n", src->name, sink->name); 3825 snd_soc_dapm_add_path(w->dapm, src, sink, NULL, NULL); 3826 } 3827 } 3828 3829 return 0; 3830} 3831 3832static void dapm_connect_dai_link_widgets(struct snd_soc_card *card, 3833 struct snd_soc_pcm_runtime *rtd) 3834{ 3835 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 3836 struct snd_soc_dapm_widget *sink, *source; 3837 int i; 3838 3839 for (i = 0; i < rtd->num_codecs; i++) { 3840 struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; 3841 3842 /* connect BE DAI playback if widgets are valid */ 3843 if (codec_dai->playback_widget && cpu_dai->playback_widget) { 3844 source = cpu_dai->playback_widget; 3845 sink = codec_dai->playback_widget; 3846 dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n", 3847 cpu_dai->component->name, source->name, 3848 codec_dai->component->name, sink->name); 3849 3850 snd_soc_dapm_add_path(&card->dapm, source, sink, 3851 NULL, NULL); 3852 } 3853 3854 /* connect BE DAI capture if widgets are valid */ 3855 if (codec_dai->capture_widget && cpu_dai->capture_widget) { 3856 source = codec_dai->capture_widget; 3857 sink = cpu_dai->capture_widget; 3858 dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n", 3859 codec_dai->component->name, source->name, 3860 cpu_dai->component->name, sink->name); 3861 3862 snd_soc_dapm_add_path(&card->dapm, source, sink, 3863 NULL, NULL); 3864 } 3865 } 3866} 3867 3868static void soc_dapm_dai_stream_event(struct snd_soc_dai *dai, int stream, 3869 int event) 3870{ 3871 struct snd_soc_dapm_widget *w; 3872 unsigned int ep; 3873 3874 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 3875 w = dai->playback_widget; 3876 else 3877 w = dai->capture_widget; 3878 3879 if (w) { 3880 dapm_mark_dirty(w, "stream event"); 3881 3882 if (w->id == snd_soc_dapm_dai_in) { 3883 ep = SND_SOC_DAPM_EP_SOURCE; 3884 dapm_widget_invalidate_input_paths(w); 3885 } else { 3886 ep = SND_SOC_DAPM_EP_SINK; 3887 dapm_widget_invalidate_output_paths(w); 3888 } 3889 3890 switch (event) { 3891 case SND_SOC_DAPM_STREAM_START: 3892 w->active = 1; 3893 w->is_ep = ep; 3894 break; 3895 case SND_SOC_DAPM_STREAM_STOP: 3896 w->active = 0; 3897 w->is_ep = 0; 3898 break; 3899 case SND_SOC_DAPM_STREAM_SUSPEND: 3900 case SND_SOC_DAPM_STREAM_RESUME: 3901 case SND_SOC_DAPM_STREAM_PAUSE_PUSH: 3902 case SND_SOC_DAPM_STREAM_PAUSE_RELEASE: 3903 break; 3904 } 3905 } 3906} 3907 3908void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card) 3909{ 3910 struct snd_soc_pcm_runtime *rtd = card->rtd; 3911 int i; 3912 3913 /* for each BE DAI link... */ 3914 for (i = 0; i < card->num_rtd; i++) { 3915 rtd = &card->rtd[i]; 3916 3917 /* 3918 * dynamic FE links have no fixed DAI mapping. 3919 * CODEC<->CODEC links have no direct connection. 3920 */ 3921 if (rtd->dai_link->dynamic || rtd->dai_link->params) 3922 continue; 3923 3924 dapm_connect_dai_link_widgets(card, rtd); 3925 } 3926} 3927 3928static void soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, 3929 int event) 3930{ 3931 int i; 3932 3933 soc_dapm_dai_stream_event(rtd->cpu_dai, stream, event); 3934 for (i = 0; i < rtd->num_codecs; i++) 3935 soc_dapm_dai_stream_event(rtd->codec_dais[i], stream, event); 3936 3937 dapm_power_widgets(rtd->card, event); 3938} 3939 3940/** 3941 * snd_soc_dapm_stream_event - send a stream event to the dapm core 3942 * @rtd: PCM runtime data 3943 * @stream: stream name 3944 * @event: stream event 3945 * 3946 * Sends a stream event to the dapm core. The core then makes any 3947 * necessary widget power changes. 3948 * 3949 * Returns 0 for success else error. 3950 */ 3951void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, 3952 int event) 3953{ 3954 struct snd_soc_card *card = rtd->card; 3955 3956 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 3957 soc_dapm_stream_event(rtd, stream, event); 3958 mutex_unlock(&card->dapm_mutex); 3959} 3960 3961/** 3962 * snd_soc_dapm_enable_pin_unlocked - enable pin. 3963 * @dapm: DAPM context 3964 * @pin: pin name 3965 * 3966 * Enables input/output pin and its parents or children widgets iff there is 3967 * a valid audio route and active audio stream. 3968 * 3969 * Requires external locking. 3970 * 3971 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 3972 * do any widget power switching. 3973 */ 3974int snd_soc_dapm_enable_pin_unlocked(struct snd_soc_dapm_context *dapm, 3975 const char *pin) 3976{ 3977 return snd_soc_dapm_set_pin(dapm, pin, 1); 3978} 3979EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin_unlocked); 3980 3981/** 3982 * snd_soc_dapm_enable_pin - enable pin. 3983 * @dapm: DAPM context 3984 * @pin: pin name 3985 * 3986 * Enables input/output pin and its parents or children widgets iff there is 3987 * a valid audio route and active audio stream. 3988 * 3989 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 3990 * do any widget power switching. 3991 */ 3992int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin) 3993{ 3994 int ret; 3995 3996 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 3997 3998 ret = snd_soc_dapm_set_pin(dapm, pin, 1); 3999 4000 mutex_unlock(&dapm->card->dapm_mutex); 4001 4002 return ret; 4003} 4004EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); 4005 4006/** 4007 * snd_soc_dapm_force_enable_pin_unlocked - force a pin to be enabled 4008 * @dapm: DAPM context 4009 * @pin: pin name 4010 * 4011 * Enables input/output pin regardless of any other state. This is 4012 * intended for use with microphone bias supplies used in microphone 4013 * jack detection. 4014 * 4015 * Requires external locking. 4016 * 4017 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 4018 * do any widget power switching. 4019 */ 4020int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm, 4021 const char *pin) 4022{ 4023 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); 4024 4025 if (!w) { 4026 dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin); 4027 return -EINVAL; 4028 } 4029 4030 dev_dbg(w->dapm->dev, "ASoC: force enable pin %s\n", pin); 4031 if (!w->connected) { 4032 /* 4033 * w->force does not affect the number of input or output paths, 4034 * so we only have to recheck if w->connected is changed 4035 */ 4036 dapm_widget_invalidate_input_paths(w); 4037 dapm_widget_invalidate_output_paths(w); 4038 w->connected = 1; 4039 } 4040 w->force = 1; 4041 dapm_mark_dirty(w, "force enable"); 4042 4043 return 0; 4044} 4045EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin_unlocked); 4046 4047/** 4048 * snd_soc_dapm_force_enable_pin - force a pin to be enabled 4049 * @dapm: DAPM context 4050 * @pin: pin name 4051 * 4052 * Enables input/output pin regardless of any other state. This is 4053 * intended for use with microphone bias supplies used in microphone 4054 * jack detection. 4055 * 4056 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 4057 * do any widget power switching. 4058 */ 4059int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, 4060 const char *pin) 4061{ 4062 int ret; 4063 4064 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 4065 4066 ret = snd_soc_dapm_force_enable_pin_unlocked(dapm, pin); 4067 4068 mutex_unlock(&dapm->card->dapm_mutex); 4069 4070 return ret; 4071} 4072EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin); 4073 4074/** 4075 * snd_soc_dapm_disable_pin_unlocked - disable pin. 4076 * @dapm: DAPM context 4077 * @pin: pin name 4078 * 4079 * Disables input/output pin and its parents or children widgets. 4080 * 4081 * Requires external locking. 4082 * 4083 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 4084 * do any widget power switching. 4085 */ 4086int snd_soc_dapm_disable_pin_unlocked(struct snd_soc_dapm_context *dapm, 4087 const char *pin) 4088{ 4089 return snd_soc_dapm_set_pin(dapm, pin, 0); 4090} 4091EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin_unlocked); 4092 4093/** 4094 * snd_soc_dapm_disable_pin - disable pin. 4095 * @dapm: DAPM context 4096 * @pin: pin name 4097 * 4098 * Disables input/output pin and its parents or children widgets. 4099 * 4100 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 4101 * do any widget power switching. 4102 */ 4103int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, 4104 const char *pin) 4105{ 4106 int ret; 4107 4108 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 4109 4110 ret = snd_soc_dapm_set_pin(dapm, pin, 0); 4111 4112 mutex_unlock(&dapm->card->dapm_mutex); 4113 4114 return ret; 4115} 4116EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); 4117 4118/** 4119 * snd_soc_dapm_nc_pin_unlocked - permanently disable pin. 4120 * @dapm: DAPM context 4121 * @pin: pin name 4122 * 4123 * Marks the specified pin as being not connected, disabling it along 4124 * any parent or child widgets. At present this is identical to 4125 * snd_soc_dapm_disable_pin() but in future it will be extended to do 4126 * additional things such as disabling controls which only affect 4127 * paths through the pin. 4128 * 4129 * Requires external locking. 4130 * 4131 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 4132 * do any widget power switching. 4133 */ 4134int snd_soc_dapm_nc_pin_unlocked(struct snd_soc_dapm_context *dapm, 4135 const char *pin) 4136{ 4137 return snd_soc_dapm_set_pin(dapm, pin, 0); 4138} 4139EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin_unlocked); 4140 4141/** 4142 * snd_soc_dapm_nc_pin - permanently disable pin. 4143 * @dapm: DAPM context 4144 * @pin: pin name 4145 * 4146 * Marks the specified pin as being not connected, disabling it along 4147 * any parent or child widgets. At present this is identical to 4148 * snd_soc_dapm_disable_pin() but in future it will be extended to do 4149 * additional things such as disabling controls which only affect 4150 * paths through the pin. 4151 * 4152 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 4153 * do any widget power switching. 4154 */ 4155int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin) 4156{ 4157 int ret; 4158 4159 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 4160 4161 ret = snd_soc_dapm_set_pin(dapm, pin, 0); 4162 4163 mutex_unlock(&dapm->card->dapm_mutex); 4164 4165 return ret; 4166} 4167EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin); 4168 4169/** 4170 * snd_soc_dapm_get_pin_status - get audio pin status 4171 * @dapm: DAPM context 4172 * @pin: audio signal pin endpoint (or start point) 4173 * 4174 * Get audio pin status - connected or disconnected. 4175 * 4176 * Returns 1 for connected otherwise 0. 4177 */ 4178int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm, 4179 const char *pin) 4180{ 4181 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); 4182 4183 if (w) 4184 return w->connected; 4185 4186 return 0; 4187} 4188EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status); 4189 4190/** 4191 * snd_soc_dapm_ignore_suspend - ignore suspend status for DAPM endpoint 4192 * @dapm: DAPM context 4193 * @pin: audio signal pin endpoint (or start point) 4194 * 4195 * Mark the given endpoint or pin as ignoring suspend. When the 4196 * system is disabled a path between two endpoints flagged as ignoring 4197 * suspend will not be disabled. The path must already be enabled via 4198 * normal means at suspend time, it will not be turned on if it was not 4199 * already enabled. 4200 */ 4201int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, 4202 const char *pin) 4203{ 4204 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, false); 4205 4206 if (!w) { 4207 dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin); 4208 return -EINVAL; 4209 } 4210 4211 w->ignore_suspend = 1; 4212 4213 return 0; 4214} 4215EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend); 4216 4217/** 4218 * snd_soc_dapm_free - free dapm resources 4219 * @dapm: DAPM context 4220 * 4221 * Free all dapm widgets and resources. 4222 */ 4223void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm) 4224{ 4225 dapm_debugfs_cleanup(dapm); 4226 dapm_free_widgets(dapm); 4227 list_del(&dapm->list); 4228} 4229EXPORT_SYMBOL_GPL(snd_soc_dapm_free); 4230 4231static void soc_dapm_shutdown_dapm(struct snd_soc_dapm_context *dapm) 4232{ 4233 struct snd_soc_card *card = dapm->card; 4234 struct snd_soc_dapm_widget *w; 4235 LIST_HEAD(down_list); 4236 int powerdown = 0; 4237 4238 mutex_lock(&card->dapm_mutex); 4239 4240 list_for_each_entry(w, &dapm->card->widgets, list) { 4241 if (w->dapm != dapm) 4242 continue; 4243 if (w->power) { 4244 dapm_seq_insert(w, &down_list, false); 4245 w->power = 0; 4246 powerdown = 1; 4247 } 4248 } 4249 4250 /* If there were no widgets to power down we're already in 4251 * standby. 4252 */ 4253 if (powerdown) { 4254 if (dapm->bias_level == SND_SOC_BIAS_ON) 4255 snd_soc_dapm_set_bias_level(dapm, 4256 SND_SOC_BIAS_PREPARE); 4257 dapm_seq_run(card, &down_list, 0, false); 4258 if (dapm->bias_level == SND_SOC_BIAS_PREPARE) 4259 snd_soc_dapm_set_bias_level(dapm, 4260 SND_SOC_BIAS_STANDBY); 4261 } 4262 4263 mutex_unlock(&card->dapm_mutex); 4264} 4265 4266/* 4267 * snd_soc_dapm_shutdown - callback for system shutdown 4268 */ 4269void snd_soc_dapm_shutdown(struct snd_soc_card *card) 4270{ 4271 struct snd_soc_dapm_context *dapm; 4272 4273 list_for_each_entry(dapm, &card->dapm_list, list) { 4274 if (dapm != &card->dapm) { 4275 soc_dapm_shutdown_dapm(dapm); 4276 if (dapm->bias_level == SND_SOC_BIAS_STANDBY) 4277 snd_soc_dapm_set_bias_level(dapm, 4278 SND_SOC_BIAS_OFF); 4279 } 4280 } 4281 4282 soc_dapm_shutdown_dapm(&card->dapm); 4283 if (card->dapm.bias_level == SND_SOC_BIAS_STANDBY) 4284 snd_soc_dapm_set_bias_level(&card->dapm, 4285 SND_SOC_BIAS_OFF); 4286} 4287 4288/* Module information */ 4289MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk"); 4290MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC"); 4291MODULE_LICENSE("GPL"); 4292