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 && !list_empty(&widget->sources))) 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 || 577 (widget->id == snd_soc_dapm_line && !list_empty(&widget->sinks))) 578 return 1; 579 } 580 581 list_for_each_entry(path, &widget->sources, list_sink) { 582 if (path->walked) 583 continue; 584 585 if (path->source && path->connect) { 586 path->walked = 1; 587 con += is_connected_input_ep(path->source); 588 } 589 } 590 591 return con; 592 } 593 594 /* 595 * Handler for generic register modifier widget. 596 */ 597 int dapm_reg_event(struct snd_soc_dapm_widget *w, 598 struct snd_kcontrol *kcontrol, int event) 599 { 600 unsigned int val; 601 602 if (SND_SOC_DAPM_EVENT_ON(event)) 603 val = w->on_val; 604 else 605 val = w->off_val; 606 607 snd_soc_update_bits(w->codec, -(w->reg + 1), 608 w->mask << w->shift, val << w->shift); 609 610 return 0; 611 } 612 EXPORT_SYMBOL_GPL(dapm_reg_event); 613 614 /* Standard power change method, used to apply power changes to most 615 * widgets. 616 */ 617 static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w) 618 { 619 int ret; 620 621 /* call any power change event handlers */ 622 if (w->event) 623 pr_debug("power %s event for %s flags %x\n", 624 w->power ? "on" : "off", 625 w->name, w->event_flags); 626 627 /* power up pre event */ 628 if (w->power && w->event && 629 (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { 630 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); 631 if (ret < 0) 632 return ret; 633 } 634 635 /* power down pre event */ 636 if (!w->power && w->event && 637 (w->event_flags & SND_SOC_DAPM_PRE_PMD)) { 638 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); 639 if (ret < 0) 640 return ret; 641 } 642 643 /* Lower PGA volume to reduce pops */ 644 if (w->id == snd_soc_dapm_pga && !w->power) 645 dapm_set_pga(w, w->power); 646 647 dapm_update_bits(w); 648 649 /* Raise PGA volume to reduce pops */ 650 if (w->id == snd_soc_dapm_pga && w->power) 651 dapm_set_pga(w, w->power); 652 653 /* power up post event */ 654 if (w->power && w->event && 655 (w->event_flags & SND_SOC_DAPM_POST_PMU)) { 656 ret = w->event(w, 657 NULL, SND_SOC_DAPM_POST_PMU); 658 if (ret < 0) 659 return ret; 660 } 661 662 /* power down post event */ 663 if (!w->power && w->event && 664 (w->event_flags & SND_SOC_DAPM_POST_PMD)) { 665 ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); 666 if (ret < 0) 667 return ret; 668 } 669 670 return 0; 671 } 672 673 /* Generic check to see if a widget should be powered. 674 */ 675 static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) 676 { 677 int in, out; 678 679 in = is_connected_input_ep(w); 680 dapm_clear_walk(w->codec); 681 out = is_connected_output_ep(w); 682 dapm_clear_walk(w->codec); 683 return out != 0 && in != 0; 684 } 685 686 /* Check to see if an ADC has power */ 687 static int dapm_adc_check_power(struct snd_soc_dapm_widget *w) 688 { 689 int in; 690 691 if (w->active) { 692 in = is_connected_input_ep(w); 693 dapm_clear_walk(w->codec); 694 return in != 0; 695 } else { 696 return dapm_generic_check_power(w); 697 } 698 } 699 700 /* Check to see if a DAC has power */ 701 static int dapm_dac_check_power(struct snd_soc_dapm_widget *w) 702 { 703 int out; 704 705 if (w->active) { 706 out = is_connected_output_ep(w); 707 dapm_clear_walk(w->codec); 708 return out != 0; 709 } else { 710 return dapm_generic_check_power(w); 711 } 712 } 713 714 /* Check to see if a power supply is needed */ 715 static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) 716 { 717 struct snd_soc_dapm_path *path; 718 int power = 0; 719 720 /* Check if one of our outputs is connected */ 721 list_for_each_entry(path, &w->sinks, list_source) { 722 if (path->sink && path->sink->power_check && 723 path->sink->power_check(path->sink)) { 724 power = 1; 725 break; 726 } 727 } 728 729 dapm_clear_walk(w->codec); 730 731 return power; 732 } 733 734 static int dapm_seq_compare(struct snd_soc_dapm_widget *a, 735 struct snd_soc_dapm_widget *b, 736 int sort[]) 737 { 738 if (sort[a->id] != sort[b->id]) 739 return sort[a->id] - sort[b->id]; 740 if (a->reg != b->reg) 741 return a->reg - b->reg; 742 743 return 0; 744 } 745 746 /* Insert a widget in order into a DAPM power sequence. */ 747 static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget, 748 struct list_head *list, 749 int sort[]) 750 { 751 struct snd_soc_dapm_widget *w; 752 753 list_for_each_entry(w, list, power_list) 754 if (dapm_seq_compare(new_widget, w, sort) < 0) { 755 list_add_tail(&new_widget->power_list, &w->power_list); 756 return; 757 } 758 759 list_add_tail(&new_widget->power_list, list); 760 } 761 762 /* Apply the coalesced changes from a DAPM sequence */ 763 static void dapm_seq_run_coalesced(struct snd_soc_codec *codec, 764 struct list_head *pending) 765 { 766 struct snd_soc_dapm_widget *w; 767 int reg, power, ret; 768 unsigned int value = 0; 769 unsigned int mask = 0; 770 unsigned int cur_mask; 771 772 reg = list_first_entry(pending, struct snd_soc_dapm_widget, 773 power_list)->reg; 774 775 list_for_each_entry(w, pending, power_list) { 776 cur_mask = 1 << w->shift; 777 BUG_ON(reg != w->reg); 778 779 if (w->invert) 780 power = !w->power; 781 else 782 power = w->power; 783 784 mask |= cur_mask; 785 if (power) 786 value |= cur_mask; 787 788 pop_dbg(codec->pop_time, 789 "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n", 790 w->name, reg, value, mask); 791 792 /* power up pre event */ 793 if (w->power && w->event && 794 (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { 795 pop_dbg(codec->pop_time, "pop test : %s PRE_PMU\n", 796 w->name); 797 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); 798 if (ret < 0) 799 pr_err("%s: pre event failed: %d\n", 800 w->name, ret); 801 } 802 803 /* power down pre event */ 804 if (!w->power && w->event && 805 (w->event_flags & SND_SOC_DAPM_PRE_PMD)) { 806 pop_dbg(codec->pop_time, "pop test : %s PRE_PMD\n", 807 w->name); 808 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); 809 if (ret < 0) 810 pr_err("%s: pre event failed: %d\n", 811 w->name, ret); 812 } 813 814 /* Lower PGA volume to reduce pops */ 815 if (w->id == snd_soc_dapm_pga && !w->power) 816 dapm_set_pga(w, w->power); 817 } 818 819 if (reg >= 0) { 820 pop_dbg(codec->pop_time, 821 "pop test : Applying 0x%x/0x%x to %x in %dms\n", 822 value, mask, reg, codec->pop_time); 823 pop_wait(codec->pop_time); 824 snd_soc_update_bits(codec, reg, mask, value); 825 } 826 827 list_for_each_entry(w, pending, power_list) { 828 /* Raise PGA volume to reduce pops */ 829 if (w->id == snd_soc_dapm_pga && w->power) 830 dapm_set_pga(w, w->power); 831 832 /* power up post event */ 833 if (w->power && w->event && 834 (w->event_flags & SND_SOC_DAPM_POST_PMU)) { 835 pop_dbg(codec->pop_time, "pop test : %s POST_PMU\n", 836 w->name); 837 ret = w->event(w, 838 NULL, SND_SOC_DAPM_POST_PMU); 839 if (ret < 0) 840 pr_err("%s: post event failed: %d\n", 841 w->name, ret); 842 } 843 844 /* power down post event */ 845 if (!w->power && w->event && 846 (w->event_flags & SND_SOC_DAPM_POST_PMD)) { 847 pop_dbg(codec->pop_time, "pop test : %s POST_PMD\n", 848 w->name); 849 ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); 850 if (ret < 0) 851 pr_err("%s: post event failed: %d\n", 852 w->name, ret); 853 } 854 } 855 } 856 857 /* Apply a DAPM power sequence. 858 * 859 * We walk over a pre-sorted list of widgets to apply power to. In 860 * order to minimise the number of writes to the device required 861 * multiple widgets will be updated in a single write where possible. 862 * Currently anything that requires more than a single write is not 863 * handled. 864 */ 865 static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list, 866 int event, int sort[]) 867 { 868 struct snd_soc_dapm_widget *w, *n; 869 LIST_HEAD(pending); 870 int cur_sort = -1; 871 int cur_reg = SND_SOC_NOPM; 872 int ret; 873 874 list_for_each_entry_safe(w, n, list, power_list) { 875 ret = 0; 876 877 /* Do we need to apply any queued changes? */ 878 if (sort[w->id] != cur_sort || w->reg != cur_reg) { 879 if (!list_empty(&pending)) 880 dapm_seq_run_coalesced(codec, &pending); 881 882 INIT_LIST_HEAD(&pending); 883 cur_sort = -1; 884 cur_reg = SND_SOC_NOPM; 885 } 886 887 switch (w->id) { 888 case snd_soc_dapm_pre: 889 if (!w->event) 890 list_for_each_entry_safe_continue(w, n, list, 891 power_list); 892 893 if (event == SND_SOC_DAPM_STREAM_START) 894 ret = w->event(w, 895 NULL, SND_SOC_DAPM_PRE_PMU); 896 else if (event == SND_SOC_DAPM_STREAM_STOP) 897 ret = w->event(w, 898 NULL, SND_SOC_DAPM_PRE_PMD); 899 break; 900 901 case snd_soc_dapm_post: 902 if (!w->event) 903 list_for_each_entry_safe_continue(w, n, list, 904 power_list); 905 906 if (event == SND_SOC_DAPM_STREAM_START) 907 ret = w->event(w, 908 NULL, SND_SOC_DAPM_POST_PMU); 909 else if (event == SND_SOC_DAPM_STREAM_STOP) 910 ret = w->event(w, 911 NULL, SND_SOC_DAPM_POST_PMD); 912 break; 913 914 case snd_soc_dapm_input: 915 case snd_soc_dapm_output: 916 case snd_soc_dapm_hp: 917 case snd_soc_dapm_mic: 918 case snd_soc_dapm_line: 919 case snd_soc_dapm_spk: 920 /* No register support currently */ 921 ret = dapm_generic_apply_power(w); 922 break; 923 924 default: 925 /* Queue it up for application */ 926 cur_sort = sort[w->id]; 927 cur_reg = w->reg; 928 list_move(&w->power_list, &pending); 929 break; 930 } 931 932 if (ret < 0) 933 pr_err("Failed to apply widget power: %d\n", 934 ret); 935 } 936 937 if (!list_empty(&pending)) 938 dapm_seq_run_coalesced(codec, &pending); 939 } 940 941 /* 942 * Scan each dapm widget for complete audio path. 943 * A complete path is a route that has valid endpoints i.e.:- 944 * 945 * o DAC to output pin. 946 * o Input Pin to ADC. 947 * o Input pin to Output pin (bypass, sidetone) 948 * o DAC to ADC (loopback). 949 */ 950 static int dapm_power_widgets(struct snd_soc_codec *codec, int event) 951 { 952 struct snd_soc_device *socdev = codec->socdev; 953 struct snd_soc_dapm_widget *w; 954 LIST_HEAD(up_list); 955 LIST_HEAD(down_list); 956 int ret = 0; 957 int power; 958 int sys_power = 0; 959 960 /* Check which widgets we need to power and store them in 961 * lists indicating if they should be powered up or down. 962 */ 963 list_for_each_entry(w, &codec->dapm_widgets, list) { 964 switch (w->id) { 965 case snd_soc_dapm_pre: 966 dapm_seq_insert(w, &down_list, dapm_down_seq); 967 break; 968 case snd_soc_dapm_post: 969 dapm_seq_insert(w, &up_list, dapm_up_seq); 970 break; 971 972 default: 973 if (!w->power_check) 974 continue; 975 976 power = w->power_check(w); 977 if (power) 978 sys_power = 1; 979 980 if (w->power == power) 981 continue; 982 983 if (power) 984 dapm_seq_insert(w, &up_list, dapm_up_seq); 985 else 986 dapm_seq_insert(w, &down_list, dapm_down_seq); 987 988 w->power = power; 989 break; 990 } 991 } 992 993 /* If there are no DAPM widgets then try to figure out power from the 994 * event type. 995 */ 996 if (list_empty(&codec->dapm_widgets)) { 997 switch (event) { 998 case SND_SOC_DAPM_STREAM_START: 999 case SND_SOC_DAPM_STREAM_RESUME: 1000 sys_power = 1; 1001 break; 1002 case SND_SOC_DAPM_STREAM_NOP: 1003 sys_power = codec->bias_level != SND_SOC_BIAS_STANDBY; 1004 default: 1005 break; 1006 } 1007 } 1008 1009 /* If we're changing to all on or all off then prepare */ 1010 if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) || 1011 (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) { 1012 ret = snd_soc_dapm_set_bias_level(socdev, 1013 SND_SOC_BIAS_PREPARE); 1014 if (ret != 0) 1015 pr_err("Failed to prepare bias: %d\n", ret); 1016 } 1017 1018 /* Power down widgets first; try to avoid amplifying pops. */ 1019 dapm_seq_run(codec, &down_list, event, dapm_down_seq); 1020 1021 /* Now power up. */ 1022 dapm_seq_run(codec, &up_list, event, dapm_up_seq); 1023 1024 /* If we just powered the last thing off drop to standby bias */ 1025 if (codec->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) { 1026 ret = snd_soc_dapm_set_bias_level(socdev, 1027 SND_SOC_BIAS_STANDBY); 1028 if (ret != 0) 1029 pr_err("Failed to apply standby bias: %d\n", ret); 1030 } 1031 1032 /* If we just powered up then move to active bias */ 1033 if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) { 1034 ret = snd_soc_dapm_set_bias_level(socdev, 1035 SND_SOC_BIAS_ON); 1036 if (ret != 0) 1037 pr_err("Failed to apply active bias: %d\n", ret); 1038 } 1039 1040 pop_dbg(codec->pop_time, "DAPM sequencing finished, waiting %dms\n", 1041 codec->pop_time); 1042 1043 return 0; 1044 } 1045 1046 #ifdef DEBUG 1047 static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action) 1048 { 1049 struct snd_soc_dapm_widget *w; 1050 struct snd_soc_dapm_path *p = NULL; 1051 int in, out; 1052 1053 printk("DAPM %s %s\n", codec->name, action); 1054 1055 list_for_each_entry(w, &codec->dapm_widgets, list) { 1056 1057 /* only display widgets that effect routing */ 1058 switch (w->id) { 1059 case snd_soc_dapm_pre: 1060 case snd_soc_dapm_post: 1061 case snd_soc_dapm_vmid: 1062 continue; 1063 case snd_soc_dapm_mux: 1064 case snd_soc_dapm_value_mux: 1065 case snd_soc_dapm_output: 1066 case snd_soc_dapm_input: 1067 case snd_soc_dapm_switch: 1068 case snd_soc_dapm_hp: 1069 case snd_soc_dapm_mic: 1070 case snd_soc_dapm_spk: 1071 case snd_soc_dapm_line: 1072 case snd_soc_dapm_micbias: 1073 case snd_soc_dapm_dac: 1074 case snd_soc_dapm_adc: 1075 case snd_soc_dapm_pga: 1076 case snd_soc_dapm_mixer: 1077 case snd_soc_dapm_mixer_named_ctl: 1078 case snd_soc_dapm_supply: 1079 case snd_soc_dapm_aif_in: 1080 case snd_soc_dapm_aif_out: 1081 if (w->name) { 1082 in = is_connected_input_ep(w); 1083 dapm_clear_walk(w->codec); 1084 out = is_connected_output_ep(w); 1085 dapm_clear_walk(w->codec); 1086 printk("%s: %s in %d out %d\n", w->name, 1087 w->power ? "On":"Off",in, out); 1088 1089 list_for_each_entry(p, &w->sources, list_sink) { 1090 if (p->connect) 1091 printk(" in %s %s\n", p->name ? p->name : "static", 1092 p->source->name); 1093 } 1094 list_for_each_entry(p, &w->sinks, list_source) { 1095 if (p->connect) 1096 printk(" out %s %s\n", p->name ? p->name : "static", 1097 p->sink->name); 1098 } 1099 } 1100 break; 1101 } 1102 } 1103 } 1104 #endif 1105 1106 #ifdef CONFIG_DEBUG_FS 1107 static int dapm_widget_power_open_file(struct inode *inode, struct file *file) 1108 { 1109 file->private_data = inode->i_private; 1110 return 0; 1111 } 1112 1113 static ssize_t dapm_widget_power_read_file(struct file *file, 1114 char __user *user_buf, 1115 size_t count, loff_t *ppos) 1116 { 1117 struct snd_soc_dapm_widget *w = file->private_data; 1118 char *buf; 1119 int in, out; 1120 ssize_t ret; 1121 struct snd_soc_dapm_path *p = NULL; 1122 1123 buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 1124 if (!buf) 1125 return -ENOMEM; 1126 1127 in = is_connected_input_ep(w); 1128 dapm_clear_walk(w->codec); 1129 out = is_connected_output_ep(w); 1130 dapm_clear_walk(w->codec); 1131 1132 ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d\n", 1133 w->name, w->power ? "On" : "Off", in, out); 1134 1135 if (w->sname) 1136 ret += snprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n", 1137 w->sname, 1138 w->active ? "active" : "inactive"); 1139 1140 list_for_each_entry(p, &w->sources, list_sink) { 1141 if (p->connect) 1142 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1143 " in %s %s\n", 1144 p->name ? p->name : "static", 1145 p->source->name); 1146 } 1147 list_for_each_entry(p, &w->sinks, list_source) { 1148 if (p->connect) 1149 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1150 " out %s %s\n", 1151 p->name ? p->name : "static", 1152 p->sink->name); 1153 } 1154 1155 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); 1156 1157 kfree(buf); 1158 return ret; 1159 } 1160 1161 static const struct file_operations dapm_widget_power_fops = { 1162 .open = dapm_widget_power_open_file, 1163 .read = dapm_widget_power_read_file, 1164 }; 1165 1166 void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec) 1167 { 1168 struct snd_soc_dapm_widget *w; 1169 struct dentry *d; 1170 1171 if (!codec->debugfs_dapm) 1172 return; 1173 1174 list_for_each_entry(w, &codec->dapm_widgets, list) { 1175 if (!w->name) 1176 continue; 1177 1178 d = debugfs_create_file(w->name, 0444, 1179 codec->debugfs_dapm, w, 1180 &dapm_widget_power_fops); 1181 if (!d) 1182 printk(KERN_WARNING 1183 "ASoC: Failed to create %s debugfs file\n", 1184 w->name); 1185 } 1186 } 1187 #else 1188 void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec) 1189 { 1190 } 1191 #endif 1192 1193 /* test and update the power status of a mux widget */ 1194 static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, 1195 struct snd_kcontrol *kcontrol, int mask, 1196 int mux, int val, struct soc_enum *e) 1197 { 1198 struct snd_soc_dapm_path *path; 1199 int found = 0; 1200 1201 if (widget->id != snd_soc_dapm_mux && 1202 widget->id != snd_soc_dapm_value_mux) 1203 return -ENODEV; 1204 1205 if (!snd_soc_test_bits(widget->codec, e->reg, mask, val)) 1206 return 0; 1207 1208 /* find dapm widget path assoc with kcontrol */ 1209 list_for_each_entry(path, &widget->codec->dapm_paths, list) { 1210 if (path->kcontrol != kcontrol) 1211 continue; 1212 1213 if (!path->name || !e->texts[mux]) 1214 continue; 1215 1216 found = 1; 1217 /* we now need to match the string in the enum to the path */ 1218 if (!(strcmp(path->name, e->texts[mux]))) 1219 path->connect = 1; /* new connection */ 1220 else 1221 path->connect = 0; /* old connection must be powered down */ 1222 } 1223 1224 if (found) { 1225 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); 1226 dump_dapm(widget->codec, "mux power update"); 1227 } 1228 1229 return 0; 1230 } 1231 1232 /* test and update the power status of a mixer or switch widget */ 1233 static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, 1234 struct snd_kcontrol *kcontrol, int reg, 1235 int val_mask, int val, int invert) 1236 { 1237 struct snd_soc_dapm_path *path; 1238 int found = 0; 1239 1240 if (widget->id != snd_soc_dapm_mixer && 1241 widget->id != snd_soc_dapm_mixer_named_ctl && 1242 widget->id != snd_soc_dapm_switch) 1243 return -ENODEV; 1244 1245 if (!snd_soc_test_bits(widget->codec, reg, val_mask, val)) 1246 return 0; 1247 1248 /* find dapm widget path assoc with kcontrol */ 1249 list_for_each_entry(path, &widget->codec->dapm_paths, list) { 1250 if (path->kcontrol != kcontrol) 1251 continue; 1252 1253 /* found, now check type */ 1254 found = 1; 1255 if (val) 1256 /* new connection */ 1257 path->connect = invert ? 0:1; 1258 else 1259 /* old connection must be powered down */ 1260 path->connect = invert ? 1:0; 1261 break; 1262 } 1263 1264 if (found) { 1265 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); 1266 dump_dapm(widget->codec, "mixer power update"); 1267 } 1268 1269 return 0; 1270 } 1271 1272 /* show dapm widget status in sys fs */ 1273 static ssize_t dapm_widget_show(struct device *dev, 1274 struct device_attribute *attr, char *buf) 1275 { 1276 struct snd_soc_device *devdata = dev_get_drvdata(dev); 1277 struct snd_soc_codec *codec = devdata->card->codec; 1278 struct snd_soc_dapm_widget *w; 1279 int count = 0; 1280 char *state = "not set"; 1281 1282 list_for_each_entry(w, &codec->dapm_widgets, list) { 1283 1284 /* only display widgets that burnm power */ 1285 switch (w->id) { 1286 case snd_soc_dapm_hp: 1287 case snd_soc_dapm_mic: 1288 case snd_soc_dapm_spk: 1289 case snd_soc_dapm_line: 1290 case snd_soc_dapm_micbias: 1291 case snd_soc_dapm_dac: 1292 case snd_soc_dapm_adc: 1293 case snd_soc_dapm_pga: 1294 case snd_soc_dapm_mixer: 1295 case snd_soc_dapm_mixer_named_ctl: 1296 case snd_soc_dapm_supply: 1297 if (w->name) 1298 count += sprintf(buf + count, "%s: %s\n", 1299 w->name, w->power ? "On":"Off"); 1300 break; 1301 default: 1302 break; 1303 } 1304 } 1305 1306 switch (codec->bias_level) { 1307 case SND_SOC_BIAS_ON: 1308 state = "On"; 1309 break; 1310 case SND_SOC_BIAS_PREPARE: 1311 state = "Prepare"; 1312 break; 1313 case SND_SOC_BIAS_STANDBY: 1314 state = "Standby"; 1315 break; 1316 case SND_SOC_BIAS_OFF: 1317 state = "Off"; 1318 break; 1319 } 1320 count += sprintf(buf + count, "PM State: %s\n", state); 1321 1322 return count; 1323 } 1324 1325 static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL); 1326 1327 int snd_soc_dapm_sys_add(struct device *dev) 1328 { 1329 return device_create_file(dev, &dev_attr_dapm_widget); 1330 } 1331 1332 static void snd_soc_dapm_sys_remove(struct device *dev) 1333 { 1334 device_remove_file(dev, &dev_attr_dapm_widget); 1335 } 1336 1337 /* free all dapm widgets and resources */ 1338 static void dapm_free_widgets(struct snd_soc_codec *codec) 1339 { 1340 struct snd_soc_dapm_widget *w, *next_w; 1341 struct snd_soc_dapm_path *p, *next_p; 1342 1343 list_for_each_entry_safe(w, next_w, &codec->dapm_widgets, list) { 1344 list_del(&w->list); 1345 kfree(w); 1346 } 1347 1348 list_for_each_entry_safe(p, next_p, &codec->dapm_paths, list) { 1349 list_del(&p->list); 1350 kfree(p->long_name); 1351 kfree(p); 1352 } 1353 } 1354 1355 static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec, 1356 const char *pin, int status) 1357 { 1358 struct snd_soc_dapm_widget *w; 1359 1360 list_for_each_entry(w, &codec->dapm_widgets, list) { 1361 if (!strcmp(w->name, pin)) { 1362 pr_debug("dapm: %s: pin %s\n", codec->name, pin); 1363 w->connected = status; 1364 return 0; 1365 } 1366 } 1367 1368 pr_err("dapm: %s: configuring unknown pin %s\n", codec->name, pin); 1369 return -EINVAL; 1370 } 1371 1372 /** 1373 * snd_soc_dapm_sync - scan and power dapm paths 1374 * @codec: audio codec 1375 * 1376 * Walks all dapm audio paths and powers widgets according to their 1377 * stream or path usage. 1378 * 1379 * Returns 0 for success. 1380 */ 1381 int snd_soc_dapm_sync(struct snd_soc_codec *codec) 1382 { 1383 int ret = dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); 1384 dump_dapm(codec, "sync"); 1385 return ret; 1386 } 1387 EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); 1388 1389 static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, 1390 const char *sink, const char *control, const char *source) 1391 { 1392 struct snd_soc_dapm_path *path; 1393 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; 1394 int ret = 0; 1395 1396 /* find src and dest widgets */ 1397 list_for_each_entry(w, &codec->dapm_widgets, list) { 1398 1399 if (!wsink && !(strcmp(w->name, sink))) { 1400 wsink = w; 1401 continue; 1402 } 1403 if (!wsource && !(strcmp(w->name, source))) { 1404 wsource = w; 1405 } 1406 } 1407 1408 if (wsource == NULL || wsink == NULL) 1409 return -ENODEV; 1410 1411 path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL); 1412 if (!path) 1413 return -ENOMEM; 1414 1415 path->source = wsource; 1416 path->sink = wsink; 1417 INIT_LIST_HEAD(&path->list); 1418 INIT_LIST_HEAD(&path->list_source); 1419 INIT_LIST_HEAD(&path->list_sink); 1420 1421 /* check for external widgets */ 1422 if (wsink->id == snd_soc_dapm_input) { 1423 if (wsource->id == snd_soc_dapm_micbias || 1424 wsource->id == snd_soc_dapm_mic || 1425 wsource->id == snd_soc_dapm_line || 1426 wsource->id == snd_soc_dapm_output) 1427 wsink->ext = 1; 1428 } 1429 if (wsource->id == snd_soc_dapm_output) { 1430 if (wsink->id == snd_soc_dapm_spk || 1431 wsink->id == snd_soc_dapm_hp || 1432 wsink->id == snd_soc_dapm_line || 1433 wsink->id == snd_soc_dapm_input) 1434 wsource->ext = 1; 1435 } 1436 1437 /* connect static paths */ 1438 if (control == NULL) { 1439 list_add(&path->list, &codec->dapm_paths); 1440 list_add(&path->list_sink, &wsink->sources); 1441 list_add(&path->list_source, &wsource->sinks); 1442 path->connect = 1; 1443 return 0; 1444 } 1445 1446 /* connect dynamic paths */ 1447 switch(wsink->id) { 1448 case snd_soc_dapm_adc: 1449 case snd_soc_dapm_dac: 1450 case snd_soc_dapm_pga: 1451 case snd_soc_dapm_input: 1452 case snd_soc_dapm_output: 1453 case snd_soc_dapm_micbias: 1454 case snd_soc_dapm_vmid: 1455 case snd_soc_dapm_pre: 1456 case snd_soc_dapm_post: 1457 case snd_soc_dapm_supply: 1458 case snd_soc_dapm_aif_in: 1459 case snd_soc_dapm_aif_out: 1460 list_add(&path->list, &codec->dapm_paths); 1461 list_add(&path->list_sink, &wsink->sources); 1462 list_add(&path->list_source, &wsource->sinks); 1463 path->connect = 1; 1464 return 0; 1465 case snd_soc_dapm_mux: 1466 case snd_soc_dapm_value_mux: 1467 ret = dapm_connect_mux(codec, wsource, wsink, path, control, 1468 &wsink->kcontrols[0]); 1469 if (ret != 0) 1470 goto err; 1471 break; 1472 case snd_soc_dapm_switch: 1473 case snd_soc_dapm_mixer: 1474 case snd_soc_dapm_mixer_named_ctl: 1475 ret = dapm_connect_mixer(codec, wsource, wsink, path, control); 1476 if (ret != 0) 1477 goto err; 1478 break; 1479 case snd_soc_dapm_hp: 1480 case snd_soc_dapm_mic: 1481 case snd_soc_dapm_line: 1482 case snd_soc_dapm_spk: 1483 list_add(&path->list, &codec->dapm_paths); 1484 list_add(&path->list_sink, &wsink->sources); 1485 list_add(&path->list_source, &wsource->sinks); 1486 path->connect = 0; 1487 return 0; 1488 } 1489 return 0; 1490 1491 err: 1492 printk(KERN_WARNING "asoc: no dapm match for %s --> %s --> %s\n", source, 1493 control, sink); 1494 kfree(path); 1495 return ret; 1496 } 1497 1498 /** 1499 * snd_soc_dapm_add_routes - Add routes between DAPM widgets 1500 * @codec: codec 1501 * @route: audio routes 1502 * @num: number of routes 1503 * 1504 * Connects 2 dapm widgets together via a named audio path. The sink is 1505 * the widget receiving the audio signal, whilst the source is the sender 1506 * of the audio signal. 1507 * 1508 * Returns 0 for success else error. On error all resources can be freed 1509 * with a call to snd_soc_card_free(). 1510 */ 1511 int snd_soc_dapm_add_routes(struct snd_soc_codec *codec, 1512 const struct snd_soc_dapm_route *route, int num) 1513 { 1514 int i, ret; 1515 1516 for (i = 0; i < num; i++) { 1517 ret = snd_soc_dapm_add_route(codec, route->sink, 1518 route->control, route->source); 1519 if (ret < 0) { 1520 printk(KERN_ERR "Failed to add route %s->%s\n", 1521 route->source, 1522 route->sink); 1523 return ret; 1524 } 1525 route++; 1526 } 1527 1528 return 0; 1529 } 1530 EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes); 1531 1532 /** 1533 * snd_soc_dapm_new_widgets - add new dapm widgets 1534 * @codec: audio codec 1535 * 1536 * Checks the codec for any new dapm widgets and creates them if found. 1537 * 1538 * Returns 0 for success. 1539 */ 1540 int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) 1541 { 1542 struct snd_soc_dapm_widget *w; 1543 1544 list_for_each_entry(w, &codec->dapm_widgets, list) 1545 { 1546 if (w->new) 1547 continue; 1548 1549 switch(w->id) { 1550 case snd_soc_dapm_switch: 1551 case snd_soc_dapm_mixer: 1552 case snd_soc_dapm_mixer_named_ctl: 1553 w->power_check = dapm_generic_check_power; 1554 dapm_new_mixer(codec, w); 1555 break; 1556 case snd_soc_dapm_mux: 1557 case snd_soc_dapm_value_mux: 1558 w->power_check = dapm_generic_check_power; 1559 dapm_new_mux(codec, w); 1560 break; 1561 case snd_soc_dapm_adc: 1562 case snd_soc_dapm_aif_out: 1563 w->power_check = dapm_adc_check_power; 1564 break; 1565 case snd_soc_dapm_dac: 1566 case snd_soc_dapm_aif_in: 1567 w->power_check = dapm_dac_check_power; 1568 break; 1569 case snd_soc_dapm_pga: 1570 w->power_check = dapm_generic_check_power; 1571 dapm_new_pga(codec, w); 1572 break; 1573 case snd_soc_dapm_input: 1574 case snd_soc_dapm_output: 1575 case snd_soc_dapm_micbias: 1576 case snd_soc_dapm_spk: 1577 case snd_soc_dapm_hp: 1578 case snd_soc_dapm_mic: 1579 case snd_soc_dapm_line: 1580 w->power_check = dapm_generic_check_power; 1581 break; 1582 case snd_soc_dapm_supply: 1583 w->power_check = dapm_supply_check_power; 1584 case snd_soc_dapm_vmid: 1585 case snd_soc_dapm_pre: 1586 case snd_soc_dapm_post: 1587 break; 1588 } 1589 w->new = 1; 1590 } 1591 1592 dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); 1593 return 0; 1594 } 1595 EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets); 1596 1597 /** 1598 * snd_soc_dapm_get_volsw - dapm mixer get callback 1599 * @kcontrol: mixer control 1600 * @ucontrol: control element information 1601 * 1602 * Callback to get the value of a dapm mixer control. 1603 * 1604 * Returns 0 for success. 1605 */ 1606 int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, 1607 struct snd_ctl_elem_value *ucontrol) 1608 { 1609 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1610 struct soc_mixer_control *mc = 1611 (struct soc_mixer_control *)kcontrol->private_value; 1612 unsigned int reg = mc->reg; 1613 unsigned int shift = mc->shift; 1614 unsigned int rshift = mc->rshift; 1615 int max = mc->max; 1616 unsigned int invert = mc->invert; 1617 unsigned int mask = (1 << fls(max)) - 1; 1618 1619 /* return the saved value if we are powered down */ 1620 if (widget->id == snd_soc_dapm_pga && !widget->power) { 1621 ucontrol->value.integer.value[0] = widget->saved_value; 1622 return 0; 1623 } 1624 1625 ucontrol->value.integer.value[0] = 1626 (snd_soc_read(widget->codec, reg) >> shift) & mask; 1627 if (shift != rshift) 1628 ucontrol->value.integer.value[1] = 1629 (snd_soc_read(widget->codec, reg) >> rshift) & mask; 1630 if (invert) { 1631 ucontrol->value.integer.value[0] = 1632 max - ucontrol->value.integer.value[0]; 1633 if (shift != rshift) 1634 ucontrol->value.integer.value[1] = 1635 max - ucontrol->value.integer.value[1]; 1636 } 1637 1638 return 0; 1639 } 1640 EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw); 1641 1642 /** 1643 * snd_soc_dapm_put_volsw - dapm mixer set callback 1644 * @kcontrol: mixer control 1645 * @ucontrol: control element information 1646 * 1647 * Callback to set the value of a dapm mixer control. 1648 * 1649 * Returns 0 for success. 1650 */ 1651 int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, 1652 struct snd_ctl_elem_value *ucontrol) 1653 { 1654 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1655 struct soc_mixer_control *mc = 1656 (struct soc_mixer_control *)kcontrol->private_value; 1657 unsigned int reg = mc->reg; 1658 unsigned int shift = mc->shift; 1659 unsigned int rshift = mc->rshift; 1660 int max = mc->max; 1661 unsigned int mask = (1 << fls(max)) - 1; 1662 unsigned int invert = mc->invert; 1663 unsigned int val, val2, val_mask; 1664 int ret; 1665 1666 val = (ucontrol->value.integer.value[0] & mask); 1667 1668 if (invert) 1669 val = max - val; 1670 val_mask = mask << shift; 1671 val = val << shift; 1672 if (shift != rshift) { 1673 val2 = (ucontrol->value.integer.value[1] & mask); 1674 if (invert) 1675 val2 = max - val2; 1676 val_mask |= mask << rshift; 1677 val |= val2 << rshift; 1678 } 1679 1680 mutex_lock(&widget->codec->mutex); 1681 widget->value = val; 1682 1683 /* save volume value if the widget is powered down */ 1684 if (widget->id == snd_soc_dapm_pga && !widget->power) { 1685 widget->saved_value = val; 1686 mutex_unlock(&widget->codec->mutex); 1687 return 1; 1688 } 1689 1690 dapm_mixer_update_power(widget, kcontrol, reg, val_mask, val, invert); 1691 if (widget->event) { 1692 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1693 ret = widget->event(widget, kcontrol, 1694 SND_SOC_DAPM_PRE_REG); 1695 if (ret < 0) { 1696 ret = 1; 1697 goto out; 1698 } 1699 } 1700 ret = snd_soc_update_bits(widget->codec, reg, val_mask, val); 1701 if (widget->event_flags & SND_SOC_DAPM_POST_REG) 1702 ret = widget->event(widget, kcontrol, 1703 SND_SOC_DAPM_POST_REG); 1704 } else 1705 ret = snd_soc_update_bits(widget->codec, reg, val_mask, val); 1706 1707 out: 1708 mutex_unlock(&widget->codec->mutex); 1709 return ret; 1710 } 1711 EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw); 1712 1713 /** 1714 * snd_soc_dapm_get_enum_double - dapm enumerated double mixer get callback 1715 * @kcontrol: mixer control 1716 * @ucontrol: control element information 1717 * 1718 * Callback to get the value of a dapm enumerated double mixer control. 1719 * 1720 * Returns 0 for success. 1721 */ 1722 int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol, 1723 struct snd_ctl_elem_value *ucontrol) 1724 { 1725 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1726 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1727 unsigned int val, bitmask; 1728 1729 for (bitmask = 1; bitmask < e->max; bitmask <<= 1) 1730 ; 1731 val = snd_soc_read(widget->codec, e->reg); 1732 ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1); 1733 if (e->shift_l != e->shift_r) 1734 ucontrol->value.enumerated.item[1] = 1735 (val >> e->shift_r) & (bitmask - 1); 1736 1737 return 0; 1738 } 1739 EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double); 1740 1741 /** 1742 * snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback 1743 * @kcontrol: mixer control 1744 * @ucontrol: control element information 1745 * 1746 * Callback to set the value of a dapm enumerated double mixer control. 1747 * 1748 * Returns 0 for success. 1749 */ 1750 int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, 1751 struct snd_ctl_elem_value *ucontrol) 1752 { 1753 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1754 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1755 unsigned int val, mux; 1756 unsigned int mask, bitmask; 1757 int ret = 0; 1758 1759 for (bitmask = 1; bitmask < e->max; bitmask <<= 1) 1760 ; 1761 if (ucontrol->value.enumerated.item[0] > e->max - 1) 1762 return -EINVAL; 1763 mux = ucontrol->value.enumerated.item[0]; 1764 val = mux << e->shift_l; 1765 mask = (bitmask - 1) << e->shift_l; 1766 if (e->shift_l != e->shift_r) { 1767 if (ucontrol->value.enumerated.item[1] > e->max - 1) 1768 return -EINVAL; 1769 val |= ucontrol->value.enumerated.item[1] << e->shift_r; 1770 mask |= (bitmask - 1) << e->shift_r; 1771 } 1772 1773 mutex_lock(&widget->codec->mutex); 1774 widget->value = val; 1775 dapm_mux_update_power(widget, kcontrol, mask, mux, val, e); 1776 if (widget->event) { 1777 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1778 ret = widget->event(widget, 1779 kcontrol, SND_SOC_DAPM_PRE_REG); 1780 if (ret < 0) 1781 goto out; 1782 } 1783 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1784 if (widget->event_flags & SND_SOC_DAPM_POST_REG) 1785 ret = widget->event(widget, 1786 kcontrol, SND_SOC_DAPM_POST_REG); 1787 } else 1788 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1789 1790 out: 1791 mutex_unlock(&widget->codec->mutex); 1792 return ret; 1793 } 1794 EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double); 1795 1796 /** 1797 * snd_soc_dapm_get_value_enum_double - dapm semi enumerated double mixer get 1798 * callback 1799 * @kcontrol: mixer control 1800 * @ucontrol: control element information 1801 * 1802 * Callback to get the value of a dapm semi enumerated double mixer control. 1803 * 1804 * Semi enumerated mixer: the enumerated items are referred as values. Can be 1805 * used for handling bitfield coded enumeration for example. 1806 * 1807 * Returns 0 for success. 1808 */ 1809 int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol, 1810 struct snd_ctl_elem_value *ucontrol) 1811 { 1812 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1813 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1814 unsigned int reg_val, val, mux; 1815 1816 reg_val = snd_soc_read(widget->codec, e->reg); 1817 val = (reg_val >> e->shift_l) & e->mask; 1818 for (mux = 0; mux < e->max; mux++) { 1819 if (val == e->values[mux]) 1820 break; 1821 } 1822 ucontrol->value.enumerated.item[0] = mux; 1823 if (e->shift_l != e->shift_r) { 1824 val = (reg_val >> e->shift_r) & e->mask; 1825 for (mux = 0; mux < e->max; mux++) { 1826 if (val == e->values[mux]) 1827 break; 1828 } 1829 ucontrol->value.enumerated.item[1] = mux; 1830 } 1831 1832 return 0; 1833 } 1834 EXPORT_SYMBOL_GPL(snd_soc_dapm_get_value_enum_double); 1835 1836 /** 1837 * snd_soc_dapm_put_value_enum_double - dapm semi enumerated double mixer set 1838 * callback 1839 * @kcontrol: mixer control 1840 * @ucontrol: control element information 1841 * 1842 * Callback to set the value of a dapm semi enumerated double mixer control. 1843 * 1844 * Semi enumerated mixer: the enumerated items are referred as values. Can be 1845 * used for handling bitfield coded enumeration for example. 1846 * 1847 * Returns 0 for success. 1848 */ 1849 int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol, 1850 struct snd_ctl_elem_value *ucontrol) 1851 { 1852 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1853 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1854 unsigned int val, mux; 1855 unsigned int mask; 1856 int ret = 0; 1857 1858 if (ucontrol->value.enumerated.item[0] > e->max - 1) 1859 return -EINVAL; 1860 mux = ucontrol->value.enumerated.item[0]; 1861 val = e->values[ucontrol->value.enumerated.item[0]] << e->shift_l; 1862 mask = e->mask << e->shift_l; 1863 if (e->shift_l != e->shift_r) { 1864 if (ucontrol->value.enumerated.item[1] > e->max - 1) 1865 return -EINVAL; 1866 val |= e->values[ucontrol->value.enumerated.item[1]] << e->shift_r; 1867 mask |= e->mask << e->shift_r; 1868 } 1869 1870 mutex_lock(&widget->codec->mutex); 1871 widget->value = val; 1872 dapm_mux_update_power(widget, kcontrol, mask, mux, val, e); 1873 if (widget->event) { 1874 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1875 ret = widget->event(widget, 1876 kcontrol, SND_SOC_DAPM_PRE_REG); 1877 if (ret < 0) 1878 goto out; 1879 } 1880 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1881 if (widget->event_flags & SND_SOC_DAPM_POST_REG) 1882 ret = widget->event(widget, 1883 kcontrol, SND_SOC_DAPM_POST_REG); 1884 } else 1885 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1886 1887 out: 1888 mutex_unlock(&widget->codec->mutex); 1889 return ret; 1890 } 1891 EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double); 1892 1893 /** 1894 * snd_soc_dapm_info_pin_switch - Info for a pin switch 1895 * 1896 * @kcontrol: mixer control 1897 * @uinfo: control element information 1898 * 1899 * Callback to provide information about a pin switch control. 1900 */ 1901 int snd_soc_dapm_info_pin_switch(struct snd_kcontrol *kcontrol, 1902 struct snd_ctl_elem_info *uinfo) 1903 { 1904 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 1905 uinfo->count = 1; 1906 uinfo->value.integer.min = 0; 1907 uinfo->value.integer.max = 1; 1908 1909 return 0; 1910 } 1911 EXPORT_SYMBOL_GPL(snd_soc_dapm_info_pin_switch); 1912 1913 /** 1914 * snd_soc_dapm_get_pin_switch - Get information for a pin switch 1915 * 1916 * @kcontrol: mixer control 1917 * @ucontrol: Value 1918 */ 1919 int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol, 1920 struct snd_ctl_elem_value *ucontrol) 1921 { 1922 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1923 const char *pin = (const char *)kcontrol->private_value; 1924 1925 mutex_lock(&codec->mutex); 1926 1927 ucontrol->value.integer.value[0] = 1928 snd_soc_dapm_get_pin_status(codec, pin); 1929 1930 mutex_unlock(&codec->mutex); 1931 1932 return 0; 1933 } 1934 EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_switch); 1935 1936 /** 1937 * snd_soc_dapm_put_pin_switch - Set information for a pin switch 1938 * 1939 * @kcontrol: mixer control 1940 * @ucontrol: Value 1941 */ 1942 int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, 1943 struct snd_ctl_elem_value *ucontrol) 1944 { 1945 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1946 const char *pin = (const char *)kcontrol->private_value; 1947 1948 mutex_lock(&codec->mutex); 1949 1950 if (ucontrol->value.integer.value[0]) 1951 snd_soc_dapm_enable_pin(codec, pin); 1952 else 1953 snd_soc_dapm_disable_pin(codec, pin); 1954 1955 snd_soc_dapm_sync(codec); 1956 1957 mutex_unlock(&codec->mutex); 1958 1959 return 0; 1960 } 1961 EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch); 1962 1963 /** 1964 * snd_soc_dapm_new_control - create new dapm control 1965 * @codec: audio codec 1966 * @widget: widget template 1967 * 1968 * Creates a new dapm control based upon the template. 1969 * 1970 * Returns 0 for success else error. 1971 */ 1972 int snd_soc_dapm_new_control(struct snd_soc_codec *codec, 1973 const struct snd_soc_dapm_widget *widget) 1974 { 1975 struct snd_soc_dapm_widget *w; 1976 1977 if ((w = dapm_cnew_widget(widget)) == NULL) 1978 return -ENOMEM; 1979 1980 w->codec = codec; 1981 INIT_LIST_HEAD(&w->sources); 1982 INIT_LIST_HEAD(&w->sinks); 1983 INIT_LIST_HEAD(&w->list); 1984 list_add(&w->list, &codec->dapm_widgets); 1985 1986 /* machine layer set ups unconnected pins and insertions */ 1987 w->connected = 1; 1988 return 0; 1989 } 1990 EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control); 1991 1992 /** 1993 * snd_soc_dapm_new_controls - create new dapm controls 1994 * @codec: audio codec 1995 * @widget: widget array 1996 * @num: number of widgets 1997 * 1998 * Creates new DAPM controls based upon the templates. 1999 * 2000 * Returns 0 for success else error. 2001 */ 2002 int snd_soc_dapm_new_controls(struct snd_soc_codec *codec, 2003 const struct snd_soc_dapm_widget *widget, 2004 int num) 2005 { 2006 int i, ret; 2007 2008 for (i = 0; i < num; i++) { 2009 ret = snd_soc_dapm_new_control(codec, widget); 2010 if (ret < 0) { 2011 printk(KERN_ERR 2012 "ASoC: Failed to create DAPM control %s: %d\n", 2013 widget->name, ret); 2014 return ret; 2015 } 2016 widget++; 2017 } 2018 return 0; 2019 } 2020 EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls); 2021 2022 2023 /** 2024 * snd_soc_dapm_stream_event - send a stream event to the dapm core 2025 * @codec: audio codec 2026 * @stream: stream name 2027 * @event: stream event 2028 * 2029 * Sends a stream event to the dapm core. The core then makes any 2030 * necessary widget power changes. 2031 * 2032 * Returns 0 for success else error. 2033 */ 2034 int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, 2035 char *stream, int event) 2036 { 2037 struct snd_soc_dapm_widget *w; 2038 2039 if (stream == NULL) 2040 return 0; 2041 2042 mutex_lock(&codec->mutex); 2043 list_for_each_entry(w, &codec->dapm_widgets, list) 2044 { 2045 if (!w->sname) 2046 continue; 2047 pr_debug("widget %s\n %s stream %s event %d\n", 2048 w->name, w->sname, stream, event); 2049 if (strstr(w->sname, stream)) { 2050 switch(event) { 2051 case SND_SOC_DAPM_STREAM_START: 2052 w->active = 1; 2053 break; 2054 case SND_SOC_DAPM_STREAM_STOP: 2055 w->active = 0; 2056 break; 2057 case SND_SOC_DAPM_STREAM_SUSPEND: 2058 if (w->active) 2059 w->suspend = 1; 2060 w->active = 0; 2061 break; 2062 case SND_SOC_DAPM_STREAM_RESUME: 2063 if (w->suspend) { 2064 w->active = 1; 2065 w->suspend = 0; 2066 } 2067 break; 2068 case SND_SOC_DAPM_STREAM_PAUSE_PUSH: 2069 break; 2070 case SND_SOC_DAPM_STREAM_PAUSE_RELEASE: 2071 break; 2072 } 2073 } 2074 } 2075 mutex_unlock(&codec->mutex); 2076 2077 dapm_power_widgets(codec, event); 2078 dump_dapm(codec, __func__); 2079 return 0; 2080 } 2081 EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event); 2082 2083 /** 2084 * snd_soc_dapm_enable_pin - enable pin. 2085 * @codec: SoC codec 2086 * @pin: pin name 2087 * 2088 * Enables input/output pin and its parents or children widgets iff there is 2089 * a valid audio route and active audio stream. 2090 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 2091 * do any widget power switching. 2092 */ 2093 int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin) 2094 { 2095 return snd_soc_dapm_set_pin(codec, pin, 1); 2096 } 2097 EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); 2098 2099 /** 2100 * snd_soc_dapm_disable_pin - disable pin. 2101 * @codec: SoC codec 2102 * @pin: pin name 2103 * 2104 * Disables input/output pin and its parents or children widgets. 2105 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 2106 * do any widget power switching. 2107 */ 2108 int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, const char *pin) 2109 { 2110 return snd_soc_dapm_set_pin(codec, pin, 0); 2111 } 2112 EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); 2113 2114 /** 2115 * snd_soc_dapm_nc_pin - permanently disable pin. 2116 * @codec: SoC codec 2117 * @pin: pin name 2118 * 2119 * Marks the specified pin as being not connected, disabling it along 2120 * any parent or child widgets. At present this is identical to 2121 * snd_soc_dapm_disable_pin() but in future it will be extended to do 2122 * additional things such as disabling controls which only affect 2123 * paths through the pin. 2124 * 2125 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 2126 * do any widget power switching. 2127 */ 2128 int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin) 2129 { 2130 return snd_soc_dapm_set_pin(codec, pin, 0); 2131 } 2132 EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin); 2133 2134 /** 2135 * snd_soc_dapm_get_pin_status - get audio pin status 2136 * @codec: audio codec 2137 * @pin: audio signal pin endpoint (or start point) 2138 * 2139 * Get audio pin status - connected or disconnected. 2140 * 2141 * Returns 1 for connected otherwise 0. 2142 */ 2143 int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin) 2144 { 2145 struct snd_soc_dapm_widget *w; 2146 2147 list_for_each_entry(w, &codec->dapm_widgets, list) { 2148 if (!strcmp(w->name, pin)) 2149 return w->connected; 2150 } 2151 2152 return 0; 2153 } 2154 EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status); 2155 2156 /** 2157 * snd_soc_dapm_free - free dapm resources 2158 * @socdev: SoC device 2159 * 2160 * Free all dapm widgets and resources. 2161 */ 2162 void snd_soc_dapm_free(struct snd_soc_device *socdev) 2163 { 2164 struct snd_soc_codec *codec = socdev->card->codec; 2165 2166 snd_soc_dapm_sys_remove(socdev->dev); 2167 dapm_free_widgets(codec); 2168 } 2169 EXPORT_SYMBOL_GPL(snd_soc_dapm_free); 2170 2171 /* 2172 * snd_soc_dapm_shutdown - callback for system shutdown 2173 */ 2174 void snd_soc_dapm_shutdown(struct snd_soc_device *socdev) 2175 { 2176 struct snd_soc_codec *codec = socdev->card->codec; 2177 struct snd_soc_dapm_widget *w; 2178 LIST_HEAD(down_list); 2179 int powerdown = 0; 2180 2181 list_for_each_entry(w, &codec->dapm_widgets, list) { 2182 if (w->power) { 2183 dapm_seq_insert(w, &down_list, dapm_down_seq); 2184 w->power = 0; 2185 powerdown = 1; 2186 } 2187 } 2188 2189 /* If there were no widgets to power down we're already in 2190 * standby. 2191 */ 2192 if (powerdown) { 2193 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_PREPARE); 2194 dapm_seq_run(codec, &down_list, 0, dapm_down_seq); 2195 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_STANDBY); 2196 } 2197 2198 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_OFF); 2199 } 2200 2201 /* Module information */ 2202 MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk"); 2203 MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC"); 2204 MODULE_LICENSE("GPL"); 2205