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