1 /* 2 * soc-dapm.c -- ALSA SoC Dynamic Audio Power Management 3 * 4 * Copyright 2005 Wolfson Microelectronics PLC. 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk> 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation; either version 2 of the License, or (at your 10 * option) any later version. 11 * 12 * Features: 13 * o Changes power status of internal codec blocks depending on the 14 * dynamic configuration of codec internal audio paths and active 15 * DACs/ADCs. 16 * o Platform power domain - can support external components i.e. amps and 17 * mic/meadphone insertion events. 18 * o Automatic Mic Bias support 19 * o Jack insertion power event initiation - e.g. hp insertion will enable 20 * sinks, dacs, etc 21 * o Delayed powerdown of audio susbsystem to reduce pops between a quick 22 * device reopen. 23 * 24 * Todo: 25 * o DAPM power change sequencing - allow for configurable per 26 * codec sequences. 27 * o Support for analogue bias optimisation. 28 * o Support for reduced codec oversampling rates. 29 * o Support for reduced codec bias currents. 30 */ 31 32 #include <linux/module.h> 33 #include <linux/moduleparam.h> 34 #include <linux/init.h> 35 #include <linux/delay.h> 36 #include <linux/pm.h> 37 #include <linux/bitops.h> 38 #include <linux/platform_device.h> 39 #include <linux/jiffies.h> 40 #include <linux/debugfs.h> 41 #include <linux/slab.h> 42 #include <sound/core.h> 43 #include <sound/pcm.h> 44 #include <sound/pcm_params.h> 45 #include <sound/soc-dapm.h> 46 #include <sound/initval.h> 47 48 /* dapm power sequences - make this per codec in the future */ 49 static int dapm_up_seq[] = { 50 [snd_soc_dapm_pre] = 0, 51 [snd_soc_dapm_supply] = 1, 52 [snd_soc_dapm_micbias] = 2, 53 [snd_soc_dapm_aif_in] = 3, 54 [snd_soc_dapm_aif_out] = 3, 55 [snd_soc_dapm_mic] = 4, 56 [snd_soc_dapm_mux] = 5, 57 [snd_soc_dapm_value_mux] = 5, 58 [snd_soc_dapm_dac] = 6, 59 [snd_soc_dapm_mixer] = 7, 60 [snd_soc_dapm_mixer_named_ctl] = 7, 61 [snd_soc_dapm_pga] = 8, 62 [snd_soc_dapm_adc] = 9, 63 [snd_soc_dapm_hp] = 10, 64 [snd_soc_dapm_spk] = 10, 65 [snd_soc_dapm_post] = 11, 66 }; 67 68 static int dapm_down_seq[] = { 69 [snd_soc_dapm_pre] = 0, 70 [snd_soc_dapm_adc] = 1, 71 [snd_soc_dapm_hp] = 2, 72 [snd_soc_dapm_spk] = 2, 73 [snd_soc_dapm_pga] = 4, 74 [snd_soc_dapm_mixer_named_ctl] = 5, 75 [snd_soc_dapm_mixer] = 5, 76 [snd_soc_dapm_dac] = 6, 77 [snd_soc_dapm_mic] = 7, 78 [snd_soc_dapm_micbias] = 8, 79 [snd_soc_dapm_mux] = 9, 80 [snd_soc_dapm_value_mux] = 9, 81 [snd_soc_dapm_aif_in] = 10, 82 [snd_soc_dapm_aif_out] = 10, 83 [snd_soc_dapm_supply] = 11, 84 [snd_soc_dapm_post] = 12, 85 }; 86 87 static void pop_wait(u32 pop_time) 88 { 89 if (pop_time) 90 schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time)); 91 } 92 93 static void pop_dbg(u32 pop_time, const char *fmt, ...) 94 { 95 va_list args; 96 97 va_start(args, fmt); 98 99 if (pop_time) { 100 vprintk(fmt, args); 101 } 102 103 va_end(args); 104 } 105 106 /* create a new dapm widget */ 107 static inline struct snd_soc_dapm_widget *dapm_cnew_widget( 108 const struct snd_soc_dapm_widget *_widget) 109 { 110 return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL); 111 } 112 113 /** 114 * snd_soc_dapm_set_bias_level - set the bias level for the system 115 * @card: audio device 116 * @level: level to configure 117 * 118 * Configure the bias (power) levels for the SoC audio device. 119 * 120 * Returns 0 for success else error. 121 */ 122 static int snd_soc_dapm_set_bias_level(struct snd_soc_card *card, 123 struct snd_soc_codec *codec, enum snd_soc_bias_level level) 124 { 125 int ret = 0; 126 127 switch (level) { 128 case SND_SOC_BIAS_ON: 129 dev_dbg(codec->dev, "Setting full bias\n"); 130 break; 131 case SND_SOC_BIAS_PREPARE: 132 dev_dbg(codec->dev, "Setting bias prepare\n"); 133 break; 134 case SND_SOC_BIAS_STANDBY: 135 dev_dbg(codec->dev, "Setting standby bias\n"); 136 break; 137 case SND_SOC_BIAS_OFF: 138 dev_dbg(codec->dev, "Setting bias off\n"); 139 break; 140 default: 141 dev_err(codec->dev, "Setting invalid bias %d\n", level); 142 return -EINVAL; 143 } 144 145 if (card && card->set_bias_level) 146 ret = card->set_bias_level(card, level); 147 if (ret == 0) { 148 if (codec->driver->set_bias_level) 149 ret = codec->driver->set_bias_level(codec, level); 150 else 151 codec->bias_level = level; 152 } 153 154 return ret; 155 } 156 157 /* set up initial codec paths */ 158 static void dapm_set_path_status(struct snd_soc_dapm_widget *w, 159 struct snd_soc_dapm_path *p, int i) 160 { 161 switch (w->id) { 162 case snd_soc_dapm_switch: 163 case snd_soc_dapm_mixer: 164 case snd_soc_dapm_mixer_named_ctl: { 165 int val; 166 struct soc_mixer_control *mc = (struct soc_mixer_control *) 167 w->kcontrols[i].private_value; 168 unsigned int reg = mc->reg; 169 unsigned int shift = mc->shift; 170 int max = mc->max; 171 unsigned int mask = (1 << fls(max)) - 1; 172 unsigned int invert = mc->invert; 173 174 val = snd_soc_read(w->codec, reg); 175 val = (val >> shift) & mask; 176 177 if ((invert && !val) || (!invert && val)) 178 p->connect = 1; 179 else 180 p->connect = 0; 181 } 182 break; 183 case snd_soc_dapm_mux: { 184 struct soc_enum *e = (struct soc_enum *)w->kcontrols[i].private_value; 185 int val, item, bitmask; 186 187 for (bitmask = 1; bitmask < e->max; bitmask <<= 1) 188 ; 189 val = snd_soc_read(w->codec, e->reg); 190 item = (val >> e->shift_l) & (bitmask - 1); 191 192 p->connect = 0; 193 for (i = 0; i < e->max; i++) { 194 if (!(strcmp(p->name, e->texts[i])) && item == i) 195 p->connect = 1; 196 } 197 } 198 break; 199 case snd_soc_dapm_value_mux: { 200 struct soc_enum *e = (struct soc_enum *) 201 w->kcontrols[i].private_value; 202 int val, item; 203 204 val = snd_soc_read(w->codec, e->reg); 205 val = (val >> e->shift_l) & e->mask; 206 for (item = 0; item < e->max; item++) { 207 if (val == e->values[item]) 208 break; 209 } 210 211 p->connect = 0; 212 for (i = 0; i < e->max; i++) { 213 if (!(strcmp(p->name, e->texts[i])) && item == i) 214 p->connect = 1; 215 } 216 } 217 break; 218 /* does not effect routing - always connected */ 219 case snd_soc_dapm_pga: 220 case snd_soc_dapm_output: 221 case snd_soc_dapm_adc: 222 case snd_soc_dapm_input: 223 case snd_soc_dapm_dac: 224 case snd_soc_dapm_micbias: 225 case snd_soc_dapm_vmid: 226 case snd_soc_dapm_supply: 227 case snd_soc_dapm_aif_in: 228 case snd_soc_dapm_aif_out: 229 p->connect = 1; 230 break; 231 /* does effect routing - dynamically connected */ 232 case snd_soc_dapm_hp: 233 case snd_soc_dapm_mic: 234 case snd_soc_dapm_spk: 235 case snd_soc_dapm_line: 236 case snd_soc_dapm_pre: 237 case snd_soc_dapm_post: 238 p->connect = 0; 239 break; 240 } 241 } 242 243 /* connect mux widget to its interconnecting audio paths */ 244 static int dapm_connect_mux(struct snd_soc_codec *codec, 245 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, 246 struct snd_soc_dapm_path *path, const char *control_name, 247 const struct snd_kcontrol_new *kcontrol) 248 { 249 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 250 int i; 251 252 for (i = 0; i < e->max; i++) { 253 if (!(strcmp(control_name, e->texts[i]))) { 254 list_add(&path->list, &codec->dapm_paths); 255 list_add(&path->list_sink, &dest->sources); 256 list_add(&path->list_source, &src->sinks); 257 path->name = (char*)e->texts[i]; 258 dapm_set_path_status(dest, path, 0); 259 return 0; 260 } 261 } 262 263 return -ENODEV; 264 } 265 266 /* connect mixer widget to its interconnecting audio paths */ 267 static int dapm_connect_mixer(struct snd_soc_codec *codec, 268 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, 269 struct snd_soc_dapm_path *path, const char *control_name) 270 { 271 int i; 272 273 /* search for mixer kcontrol */ 274 for (i = 0; i < dest->num_kcontrols; i++) { 275 if (!strcmp(control_name, dest->kcontrols[i].name)) { 276 list_add(&path->list, &codec->dapm_paths); 277 list_add(&path->list_sink, &dest->sources); 278 list_add(&path->list_source, &src->sinks); 279 path->name = dest->kcontrols[i].name; 280 dapm_set_path_status(dest, path, i); 281 return 0; 282 } 283 } 284 return -ENODEV; 285 } 286 287 /* update dapm codec register bits */ 288 static int dapm_update_bits(struct snd_soc_dapm_widget *widget) 289 { 290 int change, power; 291 unsigned int old, new; 292 struct snd_soc_codec *codec = widget->codec; 293 294 /* check for valid widgets */ 295 if (widget->reg < 0 || widget->id == snd_soc_dapm_input || 296 widget->id == snd_soc_dapm_output || 297 widget->id == snd_soc_dapm_hp || 298 widget->id == snd_soc_dapm_mic || 299 widget->id == snd_soc_dapm_line || 300 widget->id == snd_soc_dapm_spk) 301 return 0; 302 303 power = widget->power; 304 if (widget->invert) 305 power = (power ? 0:1); 306 307 old = snd_soc_read(codec, widget->reg); 308 new = (old & ~(0x1 << widget->shift)) | (power << widget->shift); 309 310 change = old != new; 311 if (change) { 312 pop_dbg(codec->pop_time, "pop test %s : %s in %d ms\n", 313 widget->name, widget->power ? "on" : "off", 314 codec->pop_time); 315 pop_wait(codec->pop_time); 316 snd_soc_write(codec, widget->reg, new); 317 } 318 pr_debug("reg %x old %x new %x change %d\n", widget->reg, 319 old, new, change); 320 return change; 321 } 322 323 /* create new dapm mixer control */ 324 static int dapm_new_mixer(struct snd_soc_codec *codec, 325 struct snd_soc_dapm_widget *w) 326 { 327 int i, ret = 0; 328 size_t name_len; 329 struct snd_soc_dapm_path *path; 330 331 /* add kcontrol */ 332 for (i = 0; i < w->num_kcontrols; i++) { 333 334 /* match name */ 335 list_for_each_entry(path, &w->sources, list_sink) { 336 337 /* mixer/mux paths name must match control name */ 338 if (path->name != (char*)w->kcontrols[i].name) 339 continue; 340 341 /* add dapm control with long name. 342 * for dapm_mixer this is the concatenation of the 343 * mixer and kcontrol name. 344 * for dapm_mixer_named_ctl this is simply the 345 * kcontrol name. 346 */ 347 name_len = strlen(w->kcontrols[i].name) + 1; 348 if (w->id != snd_soc_dapm_mixer_named_ctl) 349 name_len += 1 + strlen(w->name); 350 351 path->long_name = kmalloc(name_len, GFP_KERNEL); 352 353 if (path->long_name == NULL) 354 return -ENOMEM; 355 356 switch (w->id) { 357 default: 358 snprintf(path->long_name, name_len, "%s %s", 359 w->name, w->kcontrols[i].name); 360 break; 361 case snd_soc_dapm_mixer_named_ctl: 362 snprintf(path->long_name, name_len, "%s", 363 w->kcontrols[i].name); 364 break; 365 } 366 367 path->long_name[name_len - 1] = '\0'; 368 369 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, 370 path->long_name); 371 ret = snd_ctl_add(codec->card->snd_card, path->kcontrol); 372 if (ret < 0) { 373 printk(KERN_ERR "asoc: failed to add dapm kcontrol %s: %d\n", 374 path->long_name, 375 ret); 376 kfree(path->long_name); 377 path->long_name = NULL; 378 return ret; 379 } 380 } 381 } 382 return ret; 383 } 384 385 /* create new dapm mux control */ 386 static int dapm_new_mux(struct snd_soc_codec *codec, 387 struct snd_soc_dapm_widget *w) 388 { 389 struct snd_soc_dapm_path *path = NULL; 390 struct snd_kcontrol *kcontrol; 391 int ret = 0; 392 393 if (!w->num_kcontrols) { 394 printk(KERN_ERR "asoc: mux %s has no controls\n", w->name); 395 return -EINVAL; 396 } 397 398 kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name); 399 ret = snd_ctl_add(codec->card->snd_card, kcontrol); 400 if (ret < 0) 401 goto err; 402 403 list_for_each_entry(path, &w->sources, list_sink) 404 path->kcontrol = kcontrol; 405 406 return ret; 407 408 err: 409 printk(KERN_ERR "asoc: failed to add kcontrol %s\n", w->name); 410 return ret; 411 } 412 413 /* create new dapm volume control */ 414 static int dapm_new_pga(struct snd_soc_codec *codec, 415 struct snd_soc_dapm_widget *w) 416 { 417 if (w->num_kcontrols) 418 pr_err("asoc: PGA controls not supported: '%s'\n", w->name); 419 420 return 0; 421 } 422 423 /* reset 'walked' bit for each dapm path */ 424 static inline void dapm_clear_walk(struct snd_soc_codec *codec) 425 { 426 struct snd_soc_dapm_path *p; 427 428 list_for_each_entry(p, &codec->dapm_paths, list) 429 p->walked = 0; 430 } 431 432 /* We implement power down on suspend by checking the power state of 433 * the ALSA card - when we are suspending the ALSA state for the card 434 * is set to D3. 435 */ 436 static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget) 437 { 438 int level = snd_power_get_state(widget->codec->card->snd_card); 439 440 switch (level) { 441 case SNDRV_CTL_POWER_D3hot: 442 case SNDRV_CTL_POWER_D3cold: 443 if (widget->ignore_suspend) 444 pr_debug("%s ignoring suspend\n", widget->name); 445 return widget->ignore_suspend; 446 default: 447 return 1; 448 } 449 } 450 451 /* 452 * Recursively check for a completed path to an active or physically connected 453 * output widget. Returns number of complete paths. 454 */ 455 static int is_connected_output_ep(struct snd_soc_dapm_widget *widget) 456 { 457 struct snd_soc_dapm_path *path; 458 int con = 0; 459 460 if (widget->id == snd_soc_dapm_supply) 461 return 0; 462 463 switch (widget->id) { 464 case snd_soc_dapm_adc: 465 case snd_soc_dapm_aif_out: 466 if (widget->active) 467 return snd_soc_dapm_suspend_check(widget); 468 default: 469 break; 470 } 471 472 if (widget->connected) { 473 /* connected pin ? */ 474 if (widget->id == snd_soc_dapm_output && !widget->ext) 475 return snd_soc_dapm_suspend_check(widget); 476 477 /* connected jack or spk ? */ 478 if (widget->id == snd_soc_dapm_hp || widget->id == snd_soc_dapm_spk || 479 (widget->id == snd_soc_dapm_line && !list_empty(&widget->sources))) 480 return snd_soc_dapm_suspend_check(widget); 481 } 482 483 list_for_each_entry(path, &widget->sinks, list_source) { 484 if (path->walked) 485 continue; 486 487 if (path->sink && path->connect) { 488 path->walked = 1; 489 con += is_connected_output_ep(path->sink); 490 } 491 } 492 493 return con; 494 } 495 496 /* 497 * Recursively check for a completed path to an active or physically connected 498 * input widget. Returns number of complete paths. 499 */ 500 static int is_connected_input_ep(struct snd_soc_dapm_widget *widget) 501 { 502 struct snd_soc_dapm_path *path; 503 int con = 0; 504 505 if (widget->id == snd_soc_dapm_supply) 506 return 0; 507 508 /* active stream ? */ 509 switch (widget->id) { 510 case snd_soc_dapm_dac: 511 case snd_soc_dapm_aif_in: 512 if (widget->active) 513 return snd_soc_dapm_suspend_check(widget); 514 default: 515 break; 516 } 517 518 if (widget->connected) { 519 /* connected pin ? */ 520 if (widget->id == snd_soc_dapm_input && !widget->ext) 521 return snd_soc_dapm_suspend_check(widget); 522 523 /* connected VMID/Bias for lower pops */ 524 if (widget->id == snd_soc_dapm_vmid) 525 return snd_soc_dapm_suspend_check(widget); 526 527 /* connected jack ? */ 528 if (widget->id == snd_soc_dapm_mic || 529 (widget->id == snd_soc_dapm_line && !list_empty(&widget->sinks))) 530 return snd_soc_dapm_suspend_check(widget); 531 } 532 533 list_for_each_entry(path, &widget->sources, list_sink) { 534 if (path->walked) 535 continue; 536 537 if (path->source && path->connect) { 538 path->walked = 1; 539 con += is_connected_input_ep(path->source); 540 } 541 } 542 543 return con; 544 } 545 546 /* 547 * Handler for generic register modifier widget. 548 */ 549 int dapm_reg_event(struct snd_soc_dapm_widget *w, 550 struct snd_kcontrol *kcontrol, int event) 551 { 552 unsigned int val; 553 554 if (SND_SOC_DAPM_EVENT_ON(event)) 555 val = w->on_val; 556 else 557 val = w->off_val; 558 559 snd_soc_update_bits(w->codec, -(w->reg + 1), 560 w->mask << w->shift, val << w->shift); 561 562 return 0; 563 } 564 EXPORT_SYMBOL_GPL(dapm_reg_event); 565 566 /* Standard power change method, used to apply power changes to most 567 * widgets. 568 */ 569 static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w) 570 { 571 int ret; 572 573 /* call any power change event handlers */ 574 if (w->event) 575 pr_debug("power %s event for %s flags %x\n", 576 w->power ? "on" : "off", 577 w->name, w->event_flags); 578 579 /* power up pre event */ 580 if (w->power && w->event && 581 (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { 582 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); 583 if (ret < 0) 584 return ret; 585 } 586 587 /* power down pre event */ 588 if (!w->power && w->event && 589 (w->event_flags & SND_SOC_DAPM_PRE_PMD)) { 590 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); 591 if (ret < 0) 592 return ret; 593 } 594 595 dapm_update_bits(w); 596 597 /* power up post event */ 598 if (w->power && w->event && 599 (w->event_flags & SND_SOC_DAPM_POST_PMU)) { 600 ret = w->event(w, 601 NULL, SND_SOC_DAPM_POST_PMU); 602 if (ret < 0) 603 return ret; 604 } 605 606 /* power down post event */ 607 if (!w->power && w->event && 608 (w->event_flags & SND_SOC_DAPM_POST_PMD)) { 609 ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); 610 if (ret < 0) 611 return ret; 612 } 613 614 return 0; 615 } 616 617 /* Generic check to see if a widget should be powered. 618 */ 619 static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) 620 { 621 int in, out; 622 623 in = is_connected_input_ep(w); 624 dapm_clear_walk(w->codec); 625 out = is_connected_output_ep(w); 626 dapm_clear_walk(w->codec); 627 return out != 0 && in != 0; 628 } 629 630 /* Check to see if an ADC has power */ 631 static int dapm_adc_check_power(struct snd_soc_dapm_widget *w) 632 { 633 int in; 634 635 if (w->active) { 636 in = is_connected_input_ep(w); 637 dapm_clear_walk(w->codec); 638 return in != 0; 639 } else { 640 return dapm_generic_check_power(w); 641 } 642 } 643 644 /* Check to see if a DAC has power */ 645 static int dapm_dac_check_power(struct snd_soc_dapm_widget *w) 646 { 647 int out; 648 649 if (w->active) { 650 out = is_connected_output_ep(w); 651 dapm_clear_walk(w->codec); 652 return out != 0; 653 } else { 654 return dapm_generic_check_power(w); 655 } 656 } 657 658 /* Check to see if a power supply is needed */ 659 static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) 660 { 661 struct snd_soc_dapm_path *path; 662 int power = 0; 663 664 /* Check if one of our outputs is connected */ 665 list_for_each_entry(path, &w->sinks, list_source) { 666 if (path->connected && 667 !path->connected(path->source, path->sink)) 668 continue; 669 670 if (path->sink && path->sink->power_check && 671 path->sink->power_check(path->sink)) { 672 power = 1; 673 break; 674 } 675 } 676 677 dapm_clear_walk(w->codec); 678 679 return power; 680 } 681 682 static int dapm_seq_compare(struct snd_soc_dapm_widget *a, 683 struct snd_soc_dapm_widget *b, 684 int sort[]) 685 { 686 if (sort[a->id] != sort[b->id]) 687 return sort[a->id] - sort[b->id]; 688 if (a->reg != b->reg) 689 return a->reg - b->reg; 690 if (a->codec != b->codec) 691 return (unsigned long)a->codec - (unsigned long)b->codec; 692 693 return 0; 694 } 695 696 /* Insert a widget in order into a DAPM power sequence. */ 697 static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget, 698 struct list_head *list, 699 int sort[]) 700 { 701 struct snd_soc_dapm_widget *w; 702 703 list_for_each_entry(w, list, power_list) 704 if (dapm_seq_compare(new_widget, w, sort) < 0) { 705 list_add_tail(&new_widget->power_list, &w->power_list); 706 return; 707 } 708 709 list_add_tail(&new_widget->power_list, list); 710 } 711 712 /* Apply the coalesced changes from a DAPM sequence */ 713 static void dapm_seq_run_coalesced(struct snd_soc_codec *codec, 714 struct list_head *pending) 715 { 716 struct snd_soc_dapm_widget *w; 717 int reg, power, ret; 718 unsigned int value = 0; 719 unsigned int mask = 0; 720 unsigned int cur_mask; 721 722 reg = list_first_entry(pending, struct snd_soc_dapm_widget, 723 power_list)->reg; 724 725 list_for_each_entry(w, pending, power_list) { 726 cur_mask = 1 << w->shift; 727 BUG_ON(reg != w->reg); 728 729 if (w->invert) 730 power = !w->power; 731 else 732 power = w->power; 733 734 mask |= cur_mask; 735 if (power) 736 value |= cur_mask; 737 738 pop_dbg(codec->pop_time, 739 "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n", 740 w->name, reg, value, mask); 741 742 /* power up pre event */ 743 if (w->power && w->event && 744 (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { 745 pop_dbg(codec->pop_time, "pop test : %s PRE_PMU\n", 746 w->name); 747 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); 748 if (ret < 0) 749 pr_err("%s: pre event failed: %d\n", 750 w->name, ret); 751 } 752 753 /* power down pre event */ 754 if (!w->power && w->event && 755 (w->event_flags & SND_SOC_DAPM_PRE_PMD)) { 756 pop_dbg(codec->pop_time, "pop test : %s PRE_PMD\n", 757 w->name); 758 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); 759 if (ret < 0) 760 pr_err("%s: pre event failed: %d\n", 761 w->name, ret); 762 } 763 } 764 765 if (reg >= 0) { 766 pop_dbg(codec->pop_time, 767 "pop test : Applying 0x%x/0x%x to %x in %dms\n", 768 value, mask, reg, codec->pop_time); 769 pop_wait(codec->pop_time); 770 snd_soc_update_bits(codec, reg, mask, value); 771 } 772 773 list_for_each_entry(w, pending, power_list) { 774 /* power up post event */ 775 if (w->power && w->event && 776 (w->event_flags & SND_SOC_DAPM_POST_PMU)) { 777 pop_dbg(codec->pop_time, "pop test : %s POST_PMU\n", 778 w->name); 779 ret = w->event(w, 780 NULL, SND_SOC_DAPM_POST_PMU); 781 if (ret < 0) 782 pr_err("%s: post event failed: %d\n", 783 w->name, ret); 784 } 785 786 /* power down post event */ 787 if (!w->power && w->event && 788 (w->event_flags & SND_SOC_DAPM_POST_PMD)) { 789 pop_dbg(codec->pop_time, "pop test : %s POST_PMD\n", 790 w->name); 791 ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); 792 if (ret < 0) 793 pr_err("%s: post event failed: %d\n", 794 w->name, ret); 795 } 796 } 797 } 798 799 /* Apply a DAPM power sequence. 800 * 801 * We walk over a pre-sorted list of widgets to apply power to. In 802 * order to minimise the number of writes to the device required 803 * multiple widgets will be updated in a single write where possible. 804 * Currently anything that requires more than a single write is not 805 * handled. 806 */ 807 static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list, 808 int event, int sort[]) 809 { 810 struct snd_soc_dapm_widget *w, *n; 811 LIST_HEAD(pending); 812 int cur_sort = -1; 813 int cur_reg = SND_SOC_NOPM; 814 int ret; 815 816 list_for_each_entry_safe(w, n, list, power_list) { 817 ret = 0; 818 819 /* Do we need to apply any queued changes? */ 820 if (sort[w->id] != cur_sort || w->reg != cur_reg) { 821 if (!list_empty(&pending)) 822 dapm_seq_run_coalesced(codec, &pending); 823 824 INIT_LIST_HEAD(&pending); 825 cur_sort = -1; 826 cur_reg = SND_SOC_NOPM; 827 } 828 829 switch (w->id) { 830 case snd_soc_dapm_pre: 831 if (!w->event) 832 list_for_each_entry_safe_continue(w, n, list, 833 power_list); 834 835 if (event == SND_SOC_DAPM_STREAM_START) 836 ret = w->event(w, 837 NULL, SND_SOC_DAPM_PRE_PMU); 838 else if (event == SND_SOC_DAPM_STREAM_STOP) 839 ret = w->event(w, 840 NULL, SND_SOC_DAPM_PRE_PMD); 841 break; 842 843 case snd_soc_dapm_post: 844 if (!w->event) 845 list_for_each_entry_safe_continue(w, n, list, 846 power_list); 847 848 if (event == SND_SOC_DAPM_STREAM_START) 849 ret = w->event(w, 850 NULL, SND_SOC_DAPM_POST_PMU); 851 else if (event == SND_SOC_DAPM_STREAM_STOP) 852 ret = w->event(w, 853 NULL, SND_SOC_DAPM_POST_PMD); 854 break; 855 856 case snd_soc_dapm_input: 857 case snd_soc_dapm_output: 858 case snd_soc_dapm_hp: 859 case snd_soc_dapm_mic: 860 case snd_soc_dapm_line: 861 case snd_soc_dapm_spk: 862 /* No register support currently */ 863 ret = dapm_generic_apply_power(w); 864 break; 865 866 default: 867 /* Queue it up for application */ 868 cur_sort = sort[w->id]; 869 cur_reg = w->reg; 870 list_move(&w->power_list, &pending); 871 break; 872 } 873 874 if (ret < 0) 875 pr_err("Failed to apply widget power: %d\n", 876 ret); 877 } 878 879 if (!list_empty(&pending)) 880 dapm_seq_run_coalesced(codec, &pending); 881 } 882 883 /* 884 * Scan each dapm widget for complete audio path. 885 * A complete path is a route that has valid endpoints i.e.:- 886 * 887 * o DAC to output pin. 888 * o Input Pin to ADC. 889 * o Input pin to Output pin (bypass, sidetone) 890 * o DAC to ADC (loopback). 891 */ 892 static int dapm_power_widgets(struct snd_soc_codec *codec, int event) 893 { 894 struct snd_soc_card *card = codec->card; 895 struct snd_soc_dapm_widget *w; 896 LIST_HEAD(up_list); 897 LIST_HEAD(down_list); 898 int ret = 0; 899 int power; 900 int sys_power = 0; 901 902 /* Check which widgets we need to power and store them in 903 * lists indicating if they should be powered up or down. 904 */ 905 list_for_each_entry(w, &codec->dapm_widgets, list) { 906 switch (w->id) { 907 case snd_soc_dapm_pre: 908 dapm_seq_insert(w, &down_list, dapm_down_seq); 909 break; 910 case snd_soc_dapm_post: 911 dapm_seq_insert(w, &up_list, dapm_up_seq); 912 break; 913 914 default: 915 if (!w->power_check) 916 continue; 917 918 if (!w->force) 919 power = w->power_check(w); 920 else 921 power = 1; 922 if (power) 923 sys_power = 1; 924 925 if (w->power == power) 926 continue; 927 928 if (power) 929 dapm_seq_insert(w, &up_list, dapm_up_seq); 930 else 931 dapm_seq_insert(w, &down_list, dapm_down_seq); 932 933 w->power = power; 934 break; 935 } 936 } 937 938 /* If there are no DAPM widgets then try to figure out power from the 939 * event type. 940 */ 941 if (list_empty(&codec->dapm_widgets)) { 942 switch (event) { 943 case SND_SOC_DAPM_STREAM_START: 944 case SND_SOC_DAPM_STREAM_RESUME: 945 sys_power = 1; 946 break; 947 case SND_SOC_DAPM_STREAM_STOP: 948 sys_power = !!codec->active; 949 break; 950 case SND_SOC_DAPM_STREAM_SUSPEND: 951 sys_power = 0; 952 break; 953 case SND_SOC_DAPM_STREAM_NOP: 954 switch (codec->bias_level) { 955 case SND_SOC_BIAS_STANDBY: 956 case SND_SOC_BIAS_OFF: 957 sys_power = 0; 958 break; 959 default: 960 sys_power = 1; 961 break; 962 } 963 break; 964 default: 965 break; 966 } 967 } 968 969 if (sys_power && codec->bias_level == SND_SOC_BIAS_OFF) { 970 ret = snd_soc_dapm_set_bias_level(card, codec, 971 SND_SOC_BIAS_STANDBY); 972 if (ret != 0) 973 pr_err("Failed to turn on bias: %d\n", ret); 974 } 975 976 /* If we're changing to all on or all off then prepare */ 977 if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) || 978 (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) { 979 ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_PREPARE); 980 if (ret != 0) 981 pr_err("Failed to prepare bias: %d\n", ret); 982 } 983 984 /* Power down widgets first; try to avoid amplifying pops. */ 985 dapm_seq_run(codec, &down_list, event, dapm_down_seq); 986 987 /* Now power up. */ 988 dapm_seq_run(codec, &up_list, event, dapm_up_seq); 989 990 /* If we just powered the last thing off drop to standby bias */ 991 if (codec->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) { 992 ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_STANDBY); 993 if (ret != 0) 994 pr_err("Failed to apply standby bias: %d\n", ret); 995 } 996 997 /* If we're in standby and can support bias off then do that */ 998 if (codec->bias_level == SND_SOC_BIAS_STANDBY && 999 codec->idle_bias_off) { 1000 ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_OFF); 1001 if (ret != 0) 1002 pr_err("Failed to turn off bias: %d\n", ret); 1003 } 1004 1005 /* If we just powered up then move to active bias */ 1006 if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) { 1007 ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_ON); 1008 if (ret != 0) 1009 pr_err("Failed to apply active bias: %d\n", ret); 1010 } 1011 1012 pop_dbg(codec->pop_time, "DAPM sequencing finished, waiting %dms\n", 1013 codec->pop_time); 1014 pop_wait(codec->pop_time); 1015 1016 return 0; 1017 } 1018 1019 #ifdef CONFIG_DEBUG_FS 1020 static int dapm_widget_power_open_file(struct inode *inode, struct file *file) 1021 { 1022 file->private_data = inode->i_private; 1023 return 0; 1024 } 1025 1026 static ssize_t dapm_widget_power_read_file(struct file *file, 1027 char __user *user_buf, 1028 size_t count, loff_t *ppos) 1029 { 1030 struct snd_soc_dapm_widget *w = file->private_data; 1031 char *buf; 1032 int in, out; 1033 ssize_t ret; 1034 struct snd_soc_dapm_path *p = NULL; 1035 1036 buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 1037 if (!buf) 1038 return -ENOMEM; 1039 1040 in = is_connected_input_ep(w); 1041 dapm_clear_walk(w->codec); 1042 out = is_connected_output_ep(w); 1043 dapm_clear_walk(w->codec); 1044 1045 ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d", 1046 w->name, w->power ? "On" : "Off", in, out); 1047 1048 if (w->reg >= 0) 1049 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1050 " - R%d(0x%x) bit %d", 1051 w->reg, w->reg, w->shift); 1052 1053 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); 1054 1055 if (w->sname) 1056 ret += snprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n", 1057 w->sname, 1058 w->active ? "active" : "inactive"); 1059 1060 list_for_each_entry(p, &w->sources, list_sink) { 1061 if (p->connected && !p->connected(w, p->sink)) 1062 continue; 1063 1064 if (p->connect) 1065 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1066 " in %s %s\n", 1067 p->name ? p->name : "static", 1068 p->source->name); 1069 } 1070 list_for_each_entry(p, &w->sinks, list_source) { 1071 if (p->connected && !p->connected(w, p->sink)) 1072 continue; 1073 1074 if (p->connect) 1075 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1076 " out %s %s\n", 1077 p->name ? p->name : "static", 1078 p->sink->name); 1079 } 1080 1081 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); 1082 1083 kfree(buf); 1084 return ret; 1085 } 1086 1087 static const struct file_operations dapm_widget_power_fops = { 1088 .open = dapm_widget_power_open_file, 1089 .read = dapm_widget_power_read_file, 1090 .llseek = default_llseek, 1091 }; 1092 1093 void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec) 1094 { 1095 struct snd_soc_dapm_widget *w; 1096 struct dentry *d; 1097 1098 if (!codec->debugfs_dapm) 1099 return; 1100 1101 list_for_each_entry(w, &codec->dapm_widgets, list) { 1102 if (!w->name) 1103 continue; 1104 1105 d = debugfs_create_file(w->name, 0444, 1106 codec->debugfs_dapm, w, 1107 &dapm_widget_power_fops); 1108 if (!d) 1109 printk(KERN_WARNING 1110 "ASoC: Failed to create %s debugfs file\n", 1111 w->name); 1112 } 1113 } 1114 #else 1115 void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec) 1116 { 1117 } 1118 #endif 1119 1120 /* test and update the power status of a mux widget */ 1121 static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, 1122 struct snd_kcontrol *kcontrol, int change, 1123 int mux, struct soc_enum *e) 1124 { 1125 struct snd_soc_dapm_path *path; 1126 int found = 0; 1127 1128 if (widget->id != snd_soc_dapm_mux && 1129 widget->id != snd_soc_dapm_value_mux) 1130 return -ENODEV; 1131 1132 if (!change) 1133 return 0; 1134 1135 /* find dapm widget path assoc with kcontrol */ 1136 list_for_each_entry(path, &widget->codec->dapm_paths, list) { 1137 if (path->kcontrol != kcontrol) 1138 continue; 1139 1140 if (!path->name || !e->texts[mux]) 1141 continue; 1142 1143 found = 1; 1144 /* we now need to match the string in the enum to the path */ 1145 if (!(strcmp(path->name, e->texts[mux]))) 1146 path->connect = 1; /* new connection */ 1147 else 1148 path->connect = 0; /* old connection must be powered down */ 1149 } 1150 1151 if (found) 1152 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); 1153 1154 return 0; 1155 } 1156 1157 /* test and update the power status of a mixer or switch widget */ 1158 static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, 1159 struct snd_kcontrol *kcontrol, int connect) 1160 { 1161 struct snd_soc_dapm_path *path; 1162 int found = 0; 1163 1164 if (widget->id != snd_soc_dapm_mixer && 1165 widget->id != snd_soc_dapm_mixer_named_ctl && 1166 widget->id != snd_soc_dapm_switch) 1167 return -ENODEV; 1168 1169 /* find dapm widget path assoc with kcontrol */ 1170 list_for_each_entry(path, &widget->codec->dapm_paths, list) { 1171 if (path->kcontrol != kcontrol) 1172 continue; 1173 1174 /* found, now check type */ 1175 found = 1; 1176 path->connect = connect; 1177 break; 1178 } 1179 1180 if (found) 1181 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); 1182 1183 return 0; 1184 } 1185 1186 /* show dapm widget status in sys fs */ 1187 static ssize_t dapm_widget_show(struct device *dev, 1188 struct device_attribute *attr, char *buf) 1189 { 1190 struct snd_soc_pcm_runtime *rtd = 1191 container_of(dev, struct snd_soc_pcm_runtime, dev); 1192 struct snd_soc_codec *codec =rtd->codec; 1193 struct snd_soc_dapm_widget *w; 1194 int count = 0; 1195 char *state = "not set"; 1196 1197 list_for_each_entry(w, &codec->dapm_widgets, list) { 1198 1199 /* only display widgets that burnm power */ 1200 switch (w->id) { 1201 case snd_soc_dapm_hp: 1202 case snd_soc_dapm_mic: 1203 case snd_soc_dapm_spk: 1204 case snd_soc_dapm_line: 1205 case snd_soc_dapm_micbias: 1206 case snd_soc_dapm_dac: 1207 case snd_soc_dapm_adc: 1208 case snd_soc_dapm_pga: 1209 case snd_soc_dapm_mixer: 1210 case snd_soc_dapm_mixer_named_ctl: 1211 case snd_soc_dapm_supply: 1212 if (w->name) 1213 count += sprintf(buf + count, "%s: %s\n", 1214 w->name, w->power ? "On":"Off"); 1215 break; 1216 default: 1217 break; 1218 } 1219 } 1220 1221 switch (codec->bias_level) { 1222 case SND_SOC_BIAS_ON: 1223 state = "On"; 1224 break; 1225 case SND_SOC_BIAS_PREPARE: 1226 state = "Prepare"; 1227 break; 1228 case SND_SOC_BIAS_STANDBY: 1229 state = "Standby"; 1230 break; 1231 case SND_SOC_BIAS_OFF: 1232 state = "Off"; 1233 break; 1234 } 1235 count += sprintf(buf + count, "PM State: %s\n", state); 1236 1237 return count; 1238 } 1239 1240 static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL); 1241 1242 int snd_soc_dapm_sys_add(struct device *dev) 1243 { 1244 return device_create_file(dev, &dev_attr_dapm_widget); 1245 } 1246 1247 static void snd_soc_dapm_sys_remove(struct device *dev) 1248 { 1249 device_remove_file(dev, &dev_attr_dapm_widget); 1250 } 1251 1252 /* free all dapm widgets and resources */ 1253 static void dapm_free_widgets(struct snd_soc_codec *codec) 1254 { 1255 struct snd_soc_dapm_widget *w, *next_w; 1256 struct snd_soc_dapm_path *p, *next_p; 1257 1258 list_for_each_entry_safe(w, next_w, &codec->dapm_widgets, list) { 1259 list_del(&w->list); 1260 kfree(w); 1261 } 1262 1263 list_for_each_entry_safe(p, next_p, &codec->dapm_paths, list) { 1264 list_del(&p->list); 1265 kfree(p->long_name); 1266 kfree(p); 1267 } 1268 } 1269 1270 static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec, 1271 const char *pin, int status) 1272 { 1273 struct snd_soc_dapm_widget *w; 1274 1275 list_for_each_entry(w, &codec->dapm_widgets, list) { 1276 if (!strcmp(w->name, pin)) { 1277 pr_debug("dapm: %s: pin %s\n", codec->name, pin); 1278 w->connected = status; 1279 /* Allow disabling of forced pins */ 1280 if (status == 0) 1281 w->force = 0; 1282 return 0; 1283 } 1284 } 1285 1286 pr_err("dapm: %s: configuring unknown pin %s\n", codec->name, pin); 1287 return -EINVAL; 1288 } 1289 1290 /** 1291 * snd_soc_dapm_sync - scan and power dapm paths 1292 * @codec: audio codec 1293 * 1294 * Walks all dapm audio paths and powers widgets according to their 1295 * stream or path usage. 1296 * 1297 * Returns 0 for success. 1298 */ 1299 int snd_soc_dapm_sync(struct snd_soc_codec *codec) 1300 { 1301 return dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); 1302 } 1303 EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); 1304 1305 static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, 1306 const struct snd_soc_dapm_route *route) 1307 { 1308 struct snd_soc_dapm_path *path; 1309 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; 1310 const char *sink = route->sink; 1311 const char *control = route->control; 1312 const char *source = route->source; 1313 int ret = 0; 1314 1315 /* find src and dest widgets */ 1316 list_for_each_entry(w, &codec->dapm_widgets, list) { 1317 1318 if (!wsink && !(strcmp(w->name, sink))) { 1319 wsink = w; 1320 continue; 1321 } 1322 if (!wsource && !(strcmp(w->name, source))) { 1323 wsource = w; 1324 } 1325 } 1326 1327 if (wsource == NULL || wsink == NULL) 1328 return -ENODEV; 1329 1330 path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL); 1331 if (!path) 1332 return -ENOMEM; 1333 1334 path->source = wsource; 1335 path->sink = wsink; 1336 path->connected = route->connected; 1337 INIT_LIST_HEAD(&path->list); 1338 INIT_LIST_HEAD(&path->list_source); 1339 INIT_LIST_HEAD(&path->list_sink); 1340 1341 /* check for external widgets */ 1342 if (wsink->id == snd_soc_dapm_input) { 1343 if (wsource->id == snd_soc_dapm_micbias || 1344 wsource->id == snd_soc_dapm_mic || 1345 wsource->id == snd_soc_dapm_line || 1346 wsource->id == snd_soc_dapm_output) 1347 wsink->ext = 1; 1348 } 1349 if (wsource->id == snd_soc_dapm_output) { 1350 if (wsink->id == snd_soc_dapm_spk || 1351 wsink->id == snd_soc_dapm_hp || 1352 wsink->id == snd_soc_dapm_line || 1353 wsink->id == snd_soc_dapm_input) 1354 wsource->ext = 1; 1355 } 1356 1357 /* connect static paths */ 1358 if (control == NULL) { 1359 list_add(&path->list, &codec->dapm_paths); 1360 list_add(&path->list_sink, &wsink->sources); 1361 list_add(&path->list_source, &wsource->sinks); 1362 path->connect = 1; 1363 return 0; 1364 } 1365 1366 /* connect dynamic paths */ 1367 switch(wsink->id) { 1368 case snd_soc_dapm_adc: 1369 case snd_soc_dapm_dac: 1370 case snd_soc_dapm_pga: 1371 case snd_soc_dapm_input: 1372 case snd_soc_dapm_output: 1373 case snd_soc_dapm_micbias: 1374 case snd_soc_dapm_vmid: 1375 case snd_soc_dapm_pre: 1376 case snd_soc_dapm_post: 1377 case snd_soc_dapm_supply: 1378 case snd_soc_dapm_aif_in: 1379 case snd_soc_dapm_aif_out: 1380 list_add(&path->list, &codec->dapm_paths); 1381 list_add(&path->list_sink, &wsink->sources); 1382 list_add(&path->list_source, &wsource->sinks); 1383 path->connect = 1; 1384 return 0; 1385 case snd_soc_dapm_mux: 1386 case snd_soc_dapm_value_mux: 1387 ret = dapm_connect_mux(codec, wsource, wsink, path, control, 1388 &wsink->kcontrols[0]); 1389 if (ret != 0) 1390 goto err; 1391 break; 1392 case snd_soc_dapm_switch: 1393 case snd_soc_dapm_mixer: 1394 case snd_soc_dapm_mixer_named_ctl: 1395 ret = dapm_connect_mixer(codec, wsource, wsink, path, control); 1396 if (ret != 0) 1397 goto err; 1398 break; 1399 case snd_soc_dapm_hp: 1400 case snd_soc_dapm_mic: 1401 case snd_soc_dapm_line: 1402 case snd_soc_dapm_spk: 1403 list_add(&path->list, &codec->dapm_paths); 1404 list_add(&path->list_sink, &wsink->sources); 1405 list_add(&path->list_source, &wsource->sinks); 1406 path->connect = 0; 1407 return 0; 1408 } 1409 return 0; 1410 1411 err: 1412 printk(KERN_WARNING "asoc: no dapm match for %s --> %s --> %s\n", source, 1413 control, sink); 1414 kfree(path); 1415 return ret; 1416 } 1417 1418 /** 1419 * snd_soc_dapm_add_routes - Add routes between DAPM widgets 1420 * @codec: codec 1421 * @route: audio routes 1422 * @num: number of routes 1423 * 1424 * Connects 2 dapm widgets together via a named audio path. The sink is 1425 * the widget receiving the audio signal, whilst the source is the sender 1426 * of the audio signal. 1427 * 1428 * Returns 0 for success else error. On error all resources can be freed 1429 * with a call to snd_soc_card_free(). 1430 */ 1431 int snd_soc_dapm_add_routes(struct snd_soc_codec *codec, 1432 const struct snd_soc_dapm_route *route, int num) 1433 { 1434 int i, ret; 1435 1436 for (i = 0; i < num; i++) { 1437 ret = snd_soc_dapm_add_route(codec, route); 1438 if (ret < 0) { 1439 printk(KERN_ERR "Failed to add route %s->%s\n", 1440 route->source, 1441 route->sink); 1442 return ret; 1443 } 1444 route++; 1445 } 1446 1447 return 0; 1448 } 1449 EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes); 1450 1451 /** 1452 * snd_soc_dapm_new_widgets - add new dapm widgets 1453 * @codec: audio codec 1454 * 1455 * Checks the codec for any new dapm widgets and creates them if found. 1456 * 1457 * Returns 0 for success. 1458 */ 1459 int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) 1460 { 1461 struct snd_soc_dapm_widget *w; 1462 1463 list_for_each_entry(w, &codec->dapm_widgets, list) 1464 { 1465 if (w->new) 1466 continue; 1467 1468 switch(w->id) { 1469 case snd_soc_dapm_switch: 1470 case snd_soc_dapm_mixer: 1471 case snd_soc_dapm_mixer_named_ctl: 1472 w->power_check = dapm_generic_check_power; 1473 dapm_new_mixer(codec, w); 1474 break; 1475 case snd_soc_dapm_mux: 1476 case snd_soc_dapm_value_mux: 1477 w->power_check = dapm_generic_check_power; 1478 dapm_new_mux(codec, w); 1479 break; 1480 case snd_soc_dapm_adc: 1481 case snd_soc_dapm_aif_out: 1482 w->power_check = dapm_adc_check_power; 1483 break; 1484 case snd_soc_dapm_dac: 1485 case snd_soc_dapm_aif_in: 1486 w->power_check = dapm_dac_check_power; 1487 break; 1488 case snd_soc_dapm_pga: 1489 w->power_check = dapm_generic_check_power; 1490 dapm_new_pga(codec, w); 1491 break; 1492 case snd_soc_dapm_input: 1493 case snd_soc_dapm_output: 1494 case snd_soc_dapm_micbias: 1495 case snd_soc_dapm_spk: 1496 case snd_soc_dapm_hp: 1497 case snd_soc_dapm_mic: 1498 case snd_soc_dapm_line: 1499 w->power_check = dapm_generic_check_power; 1500 break; 1501 case snd_soc_dapm_supply: 1502 w->power_check = dapm_supply_check_power; 1503 case snd_soc_dapm_vmid: 1504 case snd_soc_dapm_pre: 1505 case snd_soc_dapm_post: 1506 break; 1507 } 1508 w->new = 1; 1509 } 1510 1511 dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); 1512 return 0; 1513 } 1514 EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets); 1515 1516 /** 1517 * snd_soc_dapm_get_volsw - dapm mixer get callback 1518 * @kcontrol: mixer control 1519 * @ucontrol: control element information 1520 * 1521 * Callback to get the value of a dapm mixer control. 1522 * 1523 * Returns 0 for success. 1524 */ 1525 int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, 1526 struct snd_ctl_elem_value *ucontrol) 1527 { 1528 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1529 struct soc_mixer_control *mc = 1530 (struct soc_mixer_control *)kcontrol->private_value; 1531 unsigned int reg = mc->reg; 1532 unsigned int shift = mc->shift; 1533 unsigned int rshift = mc->rshift; 1534 int max = mc->max; 1535 unsigned int invert = mc->invert; 1536 unsigned int mask = (1 << fls(max)) - 1; 1537 1538 ucontrol->value.integer.value[0] = 1539 (snd_soc_read(widget->codec, reg) >> shift) & mask; 1540 if (shift != rshift) 1541 ucontrol->value.integer.value[1] = 1542 (snd_soc_read(widget->codec, reg) >> rshift) & mask; 1543 if (invert) { 1544 ucontrol->value.integer.value[0] = 1545 max - ucontrol->value.integer.value[0]; 1546 if (shift != rshift) 1547 ucontrol->value.integer.value[1] = 1548 max - ucontrol->value.integer.value[1]; 1549 } 1550 1551 return 0; 1552 } 1553 EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw); 1554 1555 /** 1556 * snd_soc_dapm_put_volsw - dapm mixer set callback 1557 * @kcontrol: mixer control 1558 * @ucontrol: control element information 1559 * 1560 * Callback to set the value of a dapm mixer control. 1561 * 1562 * Returns 0 for success. 1563 */ 1564 int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, 1565 struct snd_ctl_elem_value *ucontrol) 1566 { 1567 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1568 struct soc_mixer_control *mc = 1569 (struct soc_mixer_control *)kcontrol->private_value; 1570 unsigned int reg = mc->reg; 1571 unsigned int shift = mc->shift; 1572 unsigned int rshift = mc->rshift; 1573 int max = mc->max; 1574 unsigned int mask = (1 << fls(max)) - 1; 1575 unsigned int invert = mc->invert; 1576 unsigned int val, val2, val_mask; 1577 int connect; 1578 int ret; 1579 1580 val = (ucontrol->value.integer.value[0] & mask); 1581 1582 if (invert) 1583 val = max - val; 1584 val_mask = mask << shift; 1585 val = val << shift; 1586 if (shift != rshift) { 1587 val2 = (ucontrol->value.integer.value[1] & mask); 1588 if (invert) 1589 val2 = max - val2; 1590 val_mask |= mask << rshift; 1591 val |= val2 << rshift; 1592 } 1593 1594 mutex_lock(&widget->codec->mutex); 1595 widget->value = val; 1596 1597 if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) { 1598 if (val) 1599 /* new connection */ 1600 connect = invert ? 0:1; 1601 else 1602 /* old connection must be powered down */ 1603 connect = invert ? 1:0; 1604 1605 dapm_mixer_update_power(widget, kcontrol, connect); 1606 } 1607 1608 if (widget->event) { 1609 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1610 ret = widget->event(widget, kcontrol, 1611 SND_SOC_DAPM_PRE_REG); 1612 if (ret < 0) { 1613 ret = 1; 1614 goto out; 1615 } 1616 } 1617 ret = snd_soc_update_bits(widget->codec, reg, val_mask, val); 1618 if (widget->event_flags & SND_SOC_DAPM_POST_REG) 1619 ret = widget->event(widget, kcontrol, 1620 SND_SOC_DAPM_POST_REG); 1621 } else 1622 ret = snd_soc_update_bits(widget->codec, reg, val_mask, val); 1623 1624 out: 1625 mutex_unlock(&widget->codec->mutex); 1626 return ret; 1627 } 1628 EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw); 1629 1630 /** 1631 * snd_soc_dapm_get_enum_double - dapm enumerated double mixer get callback 1632 * @kcontrol: mixer control 1633 * @ucontrol: control element information 1634 * 1635 * Callback to get the value of a dapm enumerated double mixer control. 1636 * 1637 * Returns 0 for success. 1638 */ 1639 int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol, 1640 struct snd_ctl_elem_value *ucontrol) 1641 { 1642 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1643 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1644 unsigned int val, bitmask; 1645 1646 for (bitmask = 1; bitmask < e->max; bitmask <<= 1) 1647 ; 1648 val = snd_soc_read(widget->codec, e->reg); 1649 ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1); 1650 if (e->shift_l != e->shift_r) 1651 ucontrol->value.enumerated.item[1] = 1652 (val >> e->shift_r) & (bitmask - 1); 1653 1654 return 0; 1655 } 1656 EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double); 1657 1658 /** 1659 * snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback 1660 * @kcontrol: mixer control 1661 * @ucontrol: control element information 1662 * 1663 * Callback to set the value of a dapm enumerated double mixer control. 1664 * 1665 * Returns 0 for success. 1666 */ 1667 int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, 1668 struct snd_ctl_elem_value *ucontrol) 1669 { 1670 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1671 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1672 unsigned int val, mux, change; 1673 unsigned int mask, bitmask; 1674 int ret = 0; 1675 1676 for (bitmask = 1; bitmask < e->max; bitmask <<= 1) 1677 ; 1678 if (ucontrol->value.enumerated.item[0] > e->max - 1) 1679 return -EINVAL; 1680 mux = ucontrol->value.enumerated.item[0]; 1681 val = mux << e->shift_l; 1682 mask = (bitmask - 1) << e->shift_l; 1683 if (e->shift_l != e->shift_r) { 1684 if (ucontrol->value.enumerated.item[1] > e->max - 1) 1685 return -EINVAL; 1686 val |= ucontrol->value.enumerated.item[1] << e->shift_r; 1687 mask |= (bitmask - 1) << e->shift_r; 1688 } 1689 1690 mutex_lock(&widget->codec->mutex); 1691 widget->value = val; 1692 change = snd_soc_test_bits(widget->codec, e->reg, mask, val); 1693 dapm_mux_update_power(widget, kcontrol, change, mux, e); 1694 1695 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1696 ret = widget->event(widget, 1697 kcontrol, SND_SOC_DAPM_PRE_REG); 1698 if (ret < 0) 1699 goto out; 1700 } 1701 1702 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1703 1704 if (widget->event_flags & SND_SOC_DAPM_POST_REG) 1705 ret = widget->event(widget, 1706 kcontrol, SND_SOC_DAPM_POST_REG); 1707 1708 out: 1709 mutex_unlock(&widget->codec->mutex); 1710 return ret; 1711 } 1712 EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double); 1713 1714 /** 1715 * snd_soc_dapm_get_enum_virt - Get virtual DAPM mux 1716 * @kcontrol: mixer control 1717 * @ucontrol: control element information 1718 * 1719 * Returns 0 for success. 1720 */ 1721 int snd_soc_dapm_get_enum_virt(struct snd_kcontrol *kcontrol, 1722 struct snd_ctl_elem_value *ucontrol) 1723 { 1724 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1725 1726 ucontrol->value.enumerated.item[0] = widget->value; 1727 1728 return 0; 1729 } 1730 EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_virt); 1731 1732 /** 1733 * snd_soc_dapm_put_enum_virt - Set virtual DAPM mux 1734 * @kcontrol: mixer control 1735 * @ucontrol: control element information 1736 * 1737 * Returns 0 for success. 1738 */ 1739 int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol, 1740 struct snd_ctl_elem_value *ucontrol) 1741 { 1742 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1743 struct soc_enum *e = 1744 (struct soc_enum *)kcontrol->private_value; 1745 int change; 1746 int ret = 0; 1747 1748 if (ucontrol->value.enumerated.item[0] >= e->max) 1749 return -EINVAL; 1750 1751 mutex_lock(&widget->codec->mutex); 1752 1753 change = widget->value != ucontrol->value.enumerated.item[0]; 1754 widget->value = ucontrol->value.enumerated.item[0]; 1755 dapm_mux_update_power(widget, kcontrol, change, widget->value, e); 1756 1757 mutex_unlock(&widget->codec->mutex); 1758 return ret; 1759 } 1760 EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt); 1761 1762 /** 1763 * snd_soc_dapm_get_value_enum_double - dapm semi enumerated double mixer get 1764 * callback 1765 * @kcontrol: mixer control 1766 * @ucontrol: control element information 1767 * 1768 * Callback to get the value of a dapm semi enumerated double mixer control. 1769 * 1770 * Semi enumerated mixer: the enumerated items are referred as values. Can be 1771 * used for handling bitfield coded enumeration for example. 1772 * 1773 * Returns 0 for success. 1774 */ 1775 int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol, 1776 struct snd_ctl_elem_value *ucontrol) 1777 { 1778 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1779 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1780 unsigned int reg_val, val, mux; 1781 1782 reg_val = snd_soc_read(widget->codec, e->reg); 1783 val = (reg_val >> e->shift_l) & e->mask; 1784 for (mux = 0; mux < e->max; mux++) { 1785 if (val == e->values[mux]) 1786 break; 1787 } 1788 ucontrol->value.enumerated.item[0] = mux; 1789 if (e->shift_l != e->shift_r) { 1790 val = (reg_val >> e->shift_r) & e->mask; 1791 for (mux = 0; mux < e->max; mux++) { 1792 if (val == e->values[mux]) 1793 break; 1794 } 1795 ucontrol->value.enumerated.item[1] = mux; 1796 } 1797 1798 return 0; 1799 } 1800 EXPORT_SYMBOL_GPL(snd_soc_dapm_get_value_enum_double); 1801 1802 /** 1803 * snd_soc_dapm_put_value_enum_double - dapm semi enumerated double mixer set 1804 * callback 1805 * @kcontrol: mixer control 1806 * @ucontrol: control element information 1807 * 1808 * Callback to set the value of a dapm semi enumerated double mixer control. 1809 * 1810 * Semi enumerated mixer: the enumerated items are referred as values. Can be 1811 * used for handling bitfield coded enumeration for example. 1812 * 1813 * Returns 0 for success. 1814 */ 1815 int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol, 1816 struct snd_ctl_elem_value *ucontrol) 1817 { 1818 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1819 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1820 unsigned int val, mux, change; 1821 unsigned int mask; 1822 int ret = 0; 1823 1824 if (ucontrol->value.enumerated.item[0] > e->max - 1) 1825 return -EINVAL; 1826 mux = ucontrol->value.enumerated.item[0]; 1827 val = e->values[ucontrol->value.enumerated.item[0]] << e->shift_l; 1828 mask = e->mask << e->shift_l; 1829 if (e->shift_l != e->shift_r) { 1830 if (ucontrol->value.enumerated.item[1] > e->max - 1) 1831 return -EINVAL; 1832 val |= e->values[ucontrol->value.enumerated.item[1]] << e->shift_r; 1833 mask |= e->mask << e->shift_r; 1834 } 1835 1836 mutex_lock(&widget->codec->mutex); 1837 widget->value = val; 1838 change = snd_soc_test_bits(widget->codec, e->reg, mask, val); 1839 dapm_mux_update_power(widget, kcontrol, change, mux, e); 1840 1841 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1842 ret = widget->event(widget, 1843 kcontrol, SND_SOC_DAPM_PRE_REG); 1844 if (ret < 0) 1845 goto out; 1846 } 1847 1848 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1849 1850 if (widget->event_flags & SND_SOC_DAPM_POST_REG) 1851 ret = widget->event(widget, 1852 kcontrol, SND_SOC_DAPM_POST_REG); 1853 1854 out: 1855 mutex_unlock(&widget->codec->mutex); 1856 return ret; 1857 } 1858 EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double); 1859 1860 /** 1861 * snd_soc_dapm_info_pin_switch - Info for a pin switch 1862 * 1863 * @kcontrol: mixer control 1864 * @uinfo: control element information 1865 * 1866 * Callback to provide information about a pin switch control. 1867 */ 1868 int snd_soc_dapm_info_pin_switch(struct snd_kcontrol *kcontrol, 1869 struct snd_ctl_elem_info *uinfo) 1870 { 1871 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 1872 uinfo->count = 1; 1873 uinfo->value.integer.min = 0; 1874 uinfo->value.integer.max = 1; 1875 1876 return 0; 1877 } 1878 EXPORT_SYMBOL_GPL(snd_soc_dapm_info_pin_switch); 1879 1880 /** 1881 * snd_soc_dapm_get_pin_switch - Get information for a pin switch 1882 * 1883 * @kcontrol: mixer control 1884 * @ucontrol: Value 1885 */ 1886 int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol, 1887 struct snd_ctl_elem_value *ucontrol) 1888 { 1889 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1890 const char *pin = (const char *)kcontrol->private_value; 1891 1892 mutex_lock(&codec->mutex); 1893 1894 ucontrol->value.integer.value[0] = 1895 snd_soc_dapm_get_pin_status(codec, pin); 1896 1897 mutex_unlock(&codec->mutex); 1898 1899 return 0; 1900 } 1901 EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_switch); 1902 1903 /** 1904 * snd_soc_dapm_put_pin_switch - Set information for a pin switch 1905 * 1906 * @kcontrol: mixer control 1907 * @ucontrol: Value 1908 */ 1909 int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, 1910 struct snd_ctl_elem_value *ucontrol) 1911 { 1912 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1913 const char *pin = (const char *)kcontrol->private_value; 1914 1915 mutex_lock(&codec->mutex); 1916 1917 if (ucontrol->value.integer.value[0]) 1918 snd_soc_dapm_enable_pin(codec, pin); 1919 else 1920 snd_soc_dapm_disable_pin(codec, pin); 1921 1922 snd_soc_dapm_sync(codec); 1923 1924 mutex_unlock(&codec->mutex); 1925 1926 return 0; 1927 } 1928 EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch); 1929 1930 /** 1931 * snd_soc_dapm_new_control - create new dapm control 1932 * @codec: audio codec 1933 * @widget: widget template 1934 * 1935 * Creates a new dapm control based upon the template. 1936 * 1937 * Returns 0 for success else error. 1938 */ 1939 int snd_soc_dapm_new_control(struct snd_soc_codec *codec, 1940 const struct snd_soc_dapm_widget *widget) 1941 { 1942 struct snd_soc_dapm_widget *w; 1943 1944 if ((w = dapm_cnew_widget(widget)) == NULL) 1945 return -ENOMEM; 1946 1947 w->codec = codec; 1948 INIT_LIST_HEAD(&w->sources); 1949 INIT_LIST_HEAD(&w->sinks); 1950 INIT_LIST_HEAD(&w->list); 1951 list_add(&w->list, &codec->dapm_widgets); 1952 1953 /* machine layer set ups unconnected pins and insertions */ 1954 w->connected = 1; 1955 return 0; 1956 } 1957 EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control); 1958 1959 /** 1960 * snd_soc_dapm_new_controls - create new dapm controls 1961 * @codec: audio codec 1962 * @widget: widget array 1963 * @num: number of widgets 1964 * 1965 * Creates new DAPM controls based upon the templates. 1966 * 1967 * Returns 0 for success else error. 1968 */ 1969 int snd_soc_dapm_new_controls(struct snd_soc_codec *codec, 1970 const struct snd_soc_dapm_widget *widget, 1971 int num) 1972 { 1973 int i, ret; 1974 1975 for (i = 0; i < num; i++) { 1976 ret = snd_soc_dapm_new_control(codec, widget); 1977 if (ret < 0) { 1978 printk(KERN_ERR 1979 "ASoC: Failed to create DAPM control %s: %d\n", 1980 widget->name, ret); 1981 return ret; 1982 } 1983 widget++; 1984 } 1985 return 0; 1986 } 1987 EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls); 1988 1989 1990 /** 1991 * snd_soc_dapm_stream_event - send a stream event to the dapm core 1992 * @codec: audio codec 1993 * @stream: stream name 1994 * @event: stream event 1995 * 1996 * Sends a stream event to the dapm core. The core then makes any 1997 * necessary widget power changes. 1998 * 1999 * Returns 0 for success else error. 2000 */ 2001 int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, 2002 const char *stream, int event) 2003 { 2004 struct snd_soc_codec *codec = rtd->codec; 2005 struct snd_soc_dapm_widget *w; 2006 2007 if (stream == NULL) 2008 return 0; 2009 2010 mutex_lock(&codec->mutex); 2011 list_for_each_entry(w, &codec->dapm_widgets, list) 2012 { 2013 if (!w->sname) 2014 continue; 2015 pr_debug("widget %s\n %s stream %s event %d\n", 2016 w->name, w->sname, stream, event); 2017 if (strstr(w->sname, stream)) { 2018 switch(event) { 2019 case SND_SOC_DAPM_STREAM_START: 2020 w->active = 1; 2021 break; 2022 case SND_SOC_DAPM_STREAM_STOP: 2023 w->active = 0; 2024 break; 2025 case SND_SOC_DAPM_STREAM_SUSPEND: 2026 case SND_SOC_DAPM_STREAM_RESUME: 2027 case SND_SOC_DAPM_STREAM_PAUSE_PUSH: 2028 case SND_SOC_DAPM_STREAM_PAUSE_RELEASE: 2029 break; 2030 } 2031 } 2032 } 2033 2034 dapm_power_widgets(codec, event); 2035 mutex_unlock(&codec->mutex); 2036 return 0; 2037 } 2038 EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event); 2039 2040 /** 2041 * snd_soc_dapm_enable_pin - enable pin. 2042 * @codec: SoC codec 2043 * @pin: pin name 2044 * 2045 * Enables input/output pin and its parents or children widgets iff there is 2046 * a valid audio route and active audio stream. 2047 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 2048 * do any widget power switching. 2049 */ 2050 int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin) 2051 { 2052 return snd_soc_dapm_set_pin(codec, pin, 1); 2053 } 2054 EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); 2055 2056 /** 2057 * snd_soc_dapm_force_enable_pin - force a pin to be enabled 2058 * @codec: SoC codec 2059 * @pin: pin name 2060 * 2061 * Enables input/output pin regardless of any other state. This is 2062 * intended for use with microphone bias supplies used in microphone 2063 * jack detection. 2064 * 2065 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 2066 * do any widget power switching. 2067 */ 2068 int snd_soc_dapm_force_enable_pin(struct snd_soc_codec *codec, const char *pin) 2069 { 2070 struct snd_soc_dapm_widget *w; 2071 2072 list_for_each_entry(w, &codec->dapm_widgets, list) { 2073 if (!strcmp(w->name, pin)) { 2074 pr_debug("dapm: %s: pin %s\n", codec->name, pin); 2075 w->connected = 1; 2076 w->force = 1; 2077 return 0; 2078 } 2079 } 2080 2081 pr_err("dapm: %s: configuring unknown pin %s\n", codec->name, pin); 2082 return -EINVAL; 2083 } 2084 EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin); 2085 2086 /** 2087 * snd_soc_dapm_disable_pin - disable pin. 2088 * @codec: SoC codec 2089 * @pin: pin name 2090 * 2091 * Disables input/output pin and its parents or children widgets. 2092 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 2093 * do any widget power switching. 2094 */ 2095 int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, const char *pin) 2096 { 2097 return snd_soc_dapm_set_pin(codec, pin, 0); 2098 } 2099 EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); 2100 2101 /** 2102 * snd_soc_dapm_nc_pin - permanently disable pin. 2103 * @codec: SoC codec 2104 * @pin: pin name 2105 * 2106 * Marks the specified pin as being not connected, disabling it along 2107 * any parent or child widgets. At present this is identical to 2108 * snd_soc_dapm_disable_pin() but in future it will be extended to do 2109 * additional things such as disabling controls which only affect 2110 * paths through the pin. 2111 * 2112 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 2113 * do any widget power switching. 2114 */ 2115 int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin) 2116 { 2117 return snd_soc_dapm_set_pin(codec, pin, 0); 2118 } 2119 EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin); 2120 2121 /** 2122 * snd_soc_dapm_get_pin_status - get audio pin status 2123 * @codec: audio codec 2124 * @pin: audio signal pin endpoint (or start point) 2125 * 2126 * Get audio pin status - connected or disconnected. 2127 * 2128 * Returns 1 for connected otherwise 0. 2129 */ 2130 int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin) 2131 { 2132 struct snd_soc_dapm_widget *w; 2133 2134 list_for_each_entry(w, &codec->dapm_widgets, list) { 2135 if (!strcmp(w->name, pin)) 2136 return w->connected; 2137 } 2138 2139 return 0; 2140 } 2141 EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status); 2142 2143 /** 2144 * snd_soc_dapm_ignore_suspend - ignore suspend status for DAPM endpoint 2145 * @codec: audio codec 2146 * @pin: audio signal pin endpoint (or start point) 2147 * 2148 * Mark the given endpoint or pin as ignoring suspend. When the 2149 * system is disabled a path between two endpoints flagged as ignoring 2150 * suspend will not be disabled. The path must already be enabled via 2151 * normal means at suspend time, it will not be turned on if it was not 2152 * already enabled. 2153 */ 2154 int snd_soc_dapm_ignore_suspend(struct snd_soc_codec *codec, const char *pin) 2155 { 2156 struct snd_soc_dapm_widget *w; 2157 2158 list_for_each_entry(w, &codec->dapm_widgets, list) { 2159 if (!strcmp(w->name, pin)) { 2160 w->ignore_suspend = 1; 2161 return 0; 2162 } 2163 } 2164 2165 pr_err("Unknown DAPM pin: %s\n", pin); 2166 return -EINVAL; 2167 } 2168 EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend); 2169 2170 /** 2171 * snd_soc_dapm_free - free dapm resources 2172 * @card: SoC device 2173 * 2174 * Free all dapm widgets and resources. 2175 */ 2176 void snd_soc_dapm_free(struct snd_soc_codec *codec) 2177 { 2178 snd_soc_dapm_sys_remove(codec->dev); 2179 dapm_free_widgets(codec); 2180 } 2181 EXPORT_SYMBOL_GPL(snd_soc_dapm_free); 2182 2183 static void soc_dapm_shutdown_codec(struct snd_soc_codec *codec) 2184 { 2185 struct snd_soc_dapm_widget *w; 2186 LIST_HEAD(down_list); 2187 int powerdown = 0; 2188 2189 list_for_each_entry(w, &codec->dapm_widgets, list) { 2190 if (w->power) { 2191 dapm_seq_insert(w, &down_list, dapm_down_seq); 2192 w->power = 0; 2193 powerdown = 1; 2194 } 2195 } 2196 2197 /* If there were no widgets to power down we're already in 2198 * standby. 2199 */ 2200 if (powerdown) { 2201 snd_soc_dapm_set_bias_level(NULL, codec, SND_SOC_BIAS_PREPARE); 2202 dapm_seq_run(codec, &down_list, 0, dapm_down_seq); 2203 snd_soc_dapm_set_bias_level(NULL, codec, SND_SOC_BIAS_STANDBY); 2204 } 2205 } 2206 2207 /* 2208 * snd_soc_dapm_shutdown - callback for system shutdown 2209 */ 2210 void snd_soc_dapm_shutdown(struct snd_soc_card *card) 2211 { 2212 struct snd_soc_codec *codec; 2213 2214 list_for_each_entry(codec, &card->codec_dev_list, list) 2215 soc_dapm_shutdown_codec(codec); 2216 2217 snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_OFF); 2218 } 2219 2220 /* Module information */ 2221 MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk"); 2222 MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC"); 2223 MODULE_LICENSE("GPL"); 2224