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