linux/sound/soc/soc-dapm.c
<<
>>
Prefs
   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 */
  55static 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
  74static 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
  93static void pop_wait(u32 pop_time)
  94{
  95        if (pop_time)
  96                schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time));
  97}
  98
  99static 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 */
 114static 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 */
 129static 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 */
 167static 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 */
 253static 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 */
 276static 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 */
 297static 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 */
 334static 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 */
 381static 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 */
 443static 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
 465err:
 466        printk(KERN_ERR "asoc: failed to add kcontrol %s\n", w->name);
 467        return ret;
 468}
 469
 470/* create new dapm volume control */
 471static 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 */
 491static 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 */
 503static 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 */
 548static 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 */
 597int 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}
 612EXPORT_SYMBOL_GPL(dapm_reg_event);
 613
 614/* Standard power change method, used to apply power changes to most
 615 * widgets.
 616 */
 617static 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 */
 675static 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 */
 687static 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 */
 701static 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 */
 715static 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
 734static 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. */
 747static 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 */
 763static 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 */
 865static 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 */
 950static 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                        /* If we're suspending then pull down all the 
 977                         * power. */
 978                        switch (event) {
 979                        case SND_SOC_DAPM_STREAM_SUSPEND:
 980                                power = 0;
 981                                break;
 982
 983                        default:
 984                                power = w->power_check(w);
 985                                if (power)
 986                                        sys_power = 1;
 987                                break;
 988                        }
 989
 990                        if (w->power == power)
 991                                continue;
 992
 993                        if (power)
 994                                dapm_seq_insert(w, &up_list, dapm_up_seq);
 995                        else
 996                                dapm_seq_insert(w, &down_list, dapm_down_seq);
 997
 998                        w->power = power;
 999                        break;
1000                }
1001        }
1002
1003        /* If there are no DAPM widgets then try to figure out power from the
1004         * event type.
1005         */
1006        if (list_empty(&codec->dapm_widgets)) {
1007                switch (event) {
1008                case SND_SOC_DAPM_STREAM_START:
1009                case SND_SOC_DAPM_STREAM_RESUME:
1010                        sys_power = 1;
1011                        break;
1012                case SND_SOC_DAPM_STREAM_SUSPEND:
1013                        sys_power = 0;
1014                        break;
1015                case SND_SOC_DAPM_STREAM_NOP:
1016                        sys_power = codec->bias_level != SND_SOC_BIAS_STANDBY;
1017                        break;
1018                default:
1019                        break;
1020                }
1021        }
1022
1023        /* If we're changing to all on or all off then prepare */
1024        if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) ||
1025            (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) {
1026                ret = snd_soc_dapm_set_bias_level(socdev,
1027                                                  SND_SOC_BIAS_PREPARE);
1028                if (ret != 0)
1029                        pr_err("Failed to prepare bias: %d\n", ret);
1030        }
1031
1032        /* Power down widgets first; try to avoid amplifying pops. */
1033        dapm_seq_run(codec, &down_list, event, dapm_down_seq);
1034
1035        /* Now power up. */
1036        dapm_seq_run(codec, &up_list, event, dapm_up_seq);
1037
1038        /* If we just powered the last thing off drop to standby bias */
1039        if (codec->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) {
1040                ret = snd_soc_dapm_set_bias_level(socdev,
1041                                                  SND_SOC_BIAS_STANDBY);
1042                if (ret != 0)
1043                        pr_err("Failed to apply standby bias: %d\n", ret);
1044        }
1045
1046        /* If we just powered up then move to active bias */
1047        if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) {
1048                ret = snd_soc_dapm_set_bias_level(socdev,
1049                                                  SND_SOC_BIAS_ON);
1050                if (ret != 0)
1051                        pr_err("Failed to apply active bias: %d\n", ret);
1052        }
1053
1054        pop_dbg(codec->pop_time, "DAPM sequencing finished, waiting %dms\n",
1055                codec->pop_time);
1056
1057        return 0;
1058}
1059
1060#ifdef DEBUG
1061static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action)
1062{
1063        struct snd_soc_dapm_widget *w;
1064        struct snd_soc_dapm_path *p = NULL;
1065        int in, out;
1066
1067        printk("DAPM %s %s\n", codec->name, action);
1068
1069        list_for_each_entry(w, &codec->dapm_widgets, list) {
1070
1071                /* only display widgets that effect routing */
1072                switch (w->id) {
1073                case snd_soc_dapm_pre:
1074                case snd_soc_dapm_post:
1075                case snd_soc_dapm_vmid:
1076                        continue;
1077                case snd_soc_dapm_mux:
1078                case snd_soc_dapm_value_mux:
1079                case snd_soc_dapm_output:
1080                case snd_soc_dapm_input:
1081                case snd_soc_dapm_switch:
1082                case snd_soc_dapm_hp:
1083                case snd_soc_dapm_mic:
1084                case snd_soc_dapm_spk:
1085                case snd_soc_dapm_line:
1086                case snd_soc_dapm_micbias:
1087                case snd_soc_dapm_dac:
1088                case snd_soc_dapm_adc:
1089                case snd_soc_dapm_pga:
1090                case snd_soc_dapm_mixer:
1091                case snd_soc_dapm_mixer_named_ctl:
1092                case snd_soc_dapm_supply:
1093                case snd_soc_dapm_aif_in:
1094                case snd_soc_dapm_aif_out:
1095                        if (w->name) {
1096                                in = is_connected_input_ep(w);
1097                                dapm_clear_walk(w->codec);
1098                                out = is_connected_output_ep(w);
1099                                dapm_clear_walk(w->codec);
1100                                printk("%s: %s  in %d out %d\n", w->name,
1101                                        w->power ? "On":"Off",in, out);
1102
1103                                list_for_each_entry(p, &w->sources, list_sink) {
1104                                        if (p->connect)
1105                                                printk(" in  %s %s\n", p->name ? p->name : "static",
1106                                                        p->source->name);
1107                                }
1108                                list_for_each_entry(p, &w->sinks, list_source) {
1109                                        if (p->connect)
1110                                                printk(" out %s %s\n", p->name ? p->name : "static",
1111                                                        p->sink->name);
1112                                }
1113                        }
1114                break;
1115                }
1116        }
1117}
1118#endif
1119
1120#ifdef CONFIG_DEBUG_FS
1121static int dapm_widget_power_open_file(struct inode *inode, struct file *file)
1122{
1123        file->private_data = inode->i_private;
1124        return 0;
1125}
1126
1127static ssize_t dapm_widget_power_read_file(struct file *file,
1128                                           char __user *user_buf,
1129                                           size_t count, loff_t *ppos)
1130{
1131        struct snd_soc_dapm_widget *w = file->private_data;
1132        char *buf;
1133        int in, out;
1134        ssize_t ret;
1135        struct snd_soc_dapm_path *p = NULL;
1136
1137        buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
1138        if (!buf)
1139                return -ENOMEM;
1140
1141        in = is_connected_input_ep(w);
1142        dapm_clear_walk(w->codec);
1143        out = is_connected_output_ep(w);
1144        dapm_clear_walk(w->codec);
1145
1146        ret = snprintf(buf, PAGE_SIZE, "%s: %s  in %d out %d\n",
1147                       w->name, w->power ? "On" : "Off", in, out);
1148
1149        if (w->sname)
1150                ret += snprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n",
1151                                w->sname,
1152                                w->active ? "active" : "inactive");
1153
1154        list_for_each_entry(p, &w->sources, list_sink) {
1155                if (p->connect)
1156                        ret += snprintf(buf + ret, PAGE_SIZE - ret,
1157                                        " in  %s %s\n",
1158                                        p->name ? p->name : "static",
1159                                        p->source->name);
1160        }
1161        list_for_each_entry(p, &w->sinks, list_source) {
1162                if (p->connect)
1163                        ret += snprintf(buf + ret, PAGE_SIZE - ret,
1164                                        " out %s %s\n",
1165                                        p->name ? p->name : "static",
1166                                        p->sink->name);
1167        }
1168
1169        ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
1170
1171        kfree(buf);
1172        return ret;
1173}
1174
1175static const struct file_operations dapm_widget_power_fops = {
1176        .open = dapm_widget_power_open_file,
1177        .read = dapm_widget_power_read_file,
1178};
1179
1180void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec)
1181{
1182        struct snd_soc_dapm_widget *w;
1183        struct dentry *d;
1184
1185        if (!codec->debugfs_dapm)
1186                return;
1187
1188        list_for_each_entry(w, &codec->dapm_widgets, list) {
1189                if (!w->name)
1190                        continue;
1191
1192                d = debugfs_create_file(w->name, 0444,
1193                                        codec->debugfs_dapm, w,
1194                                        &dapm_widget_power_fops);
1195                if (!d)
1196                        printk(KERN_WARNING
1197                               "ASoC: Failed to create %s debugfs file\n",
1198                               w->name);
1199        }
1200}
1201#else
1202void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec)
1203{
1204}
1205#endif
1206
1207/* test and update the power status of a mux widget */
1208static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1209                                 struct snd_kcontrol *kcontrol, int mask,
1210                                 int mux, int val, struct soc_enum *e)
1211{
1212        struct snd_soc_dapm_path *path;
1213        int found = 0;
1214
1215        if (widget->id != snd_soc_dapm_mux &&
1216            widget->id != snd_soc_dapm_value_mux)
1217                return -ENODEV;
1218
1219        if (!snd_soc_test_bits(widget->codec, e->reg, mask, val))
1220                return 0;
1221
1222        /* find dapm widget path assoc with kcontrol */
1223        list_for_each_entry(path, &widget->codec->dapm_paths, list) {
1224                if (path->kcontrol != kcontrol)
1225                        continue;
1226
1227                if (!path->name || !e->texts[mux])
1228                        continue;
1229
1230                found = 1;
1231                /* we now need to match the string in the enum to the path */
1232                if (!(strcmp(path->name, e->texts[mux])))
1233                        path->connect = 1; /* new connection */
1234                else
1235                        path->connect = 0; /* old connection must be powered down */
1236        }
1237
1238        if (found) {
1239                dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP);
1240                dump_dapm(widget->codec, "mux power update");
1241        }
1242
1243        return 0;
1244}
1245
1246/* test and update the power status of a mixer or switch widget */
1247static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1248                                   struct snd_kcontrol *kcontrol, int reg,
1249                                   int val_mask, int val, int invert)
1250{
1251        struct snd_soc_dapm_path *path;
1252        int found = 0;
1253
1254        if (widget->id != snd_soc_dapm_mixer &&
1255            widget->id != snd_soc_dapm_mixer_named_ctl &&
1256            widget->id != snd_soc_dapm_switch)
1257                return -ENODEV;
1258
1259        if (!snd_soc_test_bits(widget->codec, reg, val_mask, val))
1260                return 0;
1261
1262        /* find dapm widget path assoc with kcontrol */
1263        list_for_each_entry(path, &widget->codec->dapm_paths, list) {
1264                if (path->kcontrol != kcontrol)
1265                        continue;
1266
1267                /* found, now check type */
1268                found = 1;
1269                if (val)
1270                        /* new connection */
1271                        path->connect = invert ? 0:1;
1272                else
1273                        /* old connection must be powered down */
1274                        path->connect = invert ? 1:0;
1275                break;
1276        }
1277
1278        if (found) {
1279                dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP);
1280                dump_dapm(widget->codec, "mixer power update");
1281        }
1282
1283        return 0;
1284}
1285
1286/* show dapm widget status in sys fs */
1287static ssize_t dapm_widget_show(struct device *dev,
1288        struct device_attribute *attr, char *buf)
1289{
1290        struct snd_soc_device *devdata = dev_get_drvdata(dev);
1291        struct snd_soc_codec *codec = devdata->card->codec;
1292        struct snd_soc_dapm_widget *w;
1293        int count = 0;
1294        char *state = "not set";
1295
1296        list_for_each_entry(w, &codec->dapm_widgets, list) {
1297
1298                /* only display widgets that burnm power */
1299                switch (w->id) {
1300                case snd_soc_dapm_hp:
1301                case snd_soc_dapm_mic:
1302                case snd_soc_dapm_spk:
1303                case snd_soc_dapm_line:
1304                case snd_soc_dapm_micbias:
1305                case snd_soc_dapm_dac:
1306                case snd_soc_dapm_adc:
1307                case snd_soc_dapm_pga:
1308                case snd_soc_dapm_mixer:
1309                case snd_soc_dapm_mixer_named_ctl:
1310                case snd_soc_dapm_supply:
1311                        if (w->name)
1312                                count += sprintf(buf + count, "%s: %s\n",
1313                                        w->name, w->power ? "On":"Off");
1314                break;
1315                default:
1316                break;
1317                }
1318        }
1319
1320        switch (codec->bias_level) {
1321        case SND_SOC_BIAS_ON:
1322                state = "On";
1323                break;
1324        case SND_SOC_BIAS_PREPARE:
1325                state = "Prepare";
1326                break;
1327        case SND_SOC_BIAS_STANDBY:
1328                state = "Standby";
1329                break;
1330        case SND_SOC_BIAS_OFF:
1331                state = "Off";
1332                break;
1333        }
1334        count += sprintf(buf + count, "PM State: %s\n", state);
1335
1336        return count;
1337}
1338
1339static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL);
1340
1341int snd_soc_dapm_sys_add(struct device *dev)
1342{
1343        return device_create_file(dev, &dev_attr_dapm_widget);
1344}
1345
1346static void snd_soc_dapm_sys_remove(struct device *dev)
1347{
1348        device_remove_file(dev, &dev_attr_dapm_widget);
1349}
1350
1351/* free all dapm widgets and resources */
1352static void dapm_free_widgets(struct snd_soc_codec *codec)
1353{
1354        struct snd_soc_dapm_widget *w, *next_w;
1355        struct snd_soc_dapm_path *p, *next_p;
1356
1357        list_for_each_entry_safe(w, next_w, &codec->dapm_widgets, list) {
1358                list_del(&w->list);
1359                kfree(w);
1360        }
1361
1362        list_for_each_entry_safe(p, next_p, &codec->dapm_paths, list) {
1363                list_del(&p->list);
1364                kfree(p->long_name);
1365                kfree(p);
1366        }
1367}
1368
1369static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec,
1370                                const char *pin, int status)
1371{
1372        struct snd_soc_dapm_widget *w;
1373
1374        list_for_each_entry(w, &codec->dapm_widgets, list) {
1375                if (!strcmp(w->name, pin)) {
1376                        pr_debug("dapm: %s: pin %s\n", codec->name, pin);
1377                        w->connected = status;
1378                        return 0;
1379                }
1380        }
1381
1382        pr_err("dapm: %s: configuring unknown pin %s\n", codec->name, pin);
1383        return -EINVAL;
1384}
1385
1386/**
1387 * snd_soc_dapm_sync - scan and power dapm paths
1388 * @codec: audio codec
1389 *
1390 * Walks all dapm audio paths and powers widgets according to their
1391 * stream or path usage.
1392 *
1393 * Returns 0 for success.
1394 */
1395int snd_soc_dapm_sync(struct snd_soc_codec *codec)
1396{
1397        int ret = dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP);
1398        dump_dapm(codec, "sync");
1399        return ret;
1400}
1401EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
1402
1403static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
1404        const char *sink, const char *control, const char *source)
1405{
1406        struct snd_soc_dapm_path *path;
1407        struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w;
1408        int ret = 0;
1409
1410        /* find src and dest widgets */
1411        list_for_each_entry(w, &codec->dapm_widgets, list) {
1412
1413                if (!wsink && !(strcmp(w->name, sink))) {
1414                        wsink = w;
1415                        continue;
1416                }
1417                if (!wsource && !(strcmp(w->name, source))) {
1418                        wsource = w;
1419                }
1420        }
1421
1422        if (wsource == NULL || wsink == NULL)
1423                return -ENODEV;
1424
1425        path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL);
1426        if (!path)
1427                return -ENOMEM;
1428
1429        path->source = wsource;
1430        path->sink = wsink;
1431        INIT_LIST_HEAD(&path->list);
1432        INIT_LIST_HEAD(&path->list_source);
1433        INIT_LIST_HEAD(&path->list_sink);
1434
1435        /* check for external widgets */
1436        if (wsink->id == snd_soc_dapm_input) {
1437                if (wsource->id == snd_soc_dapm_micbias ||
1438                        wsource->id == snd_soc_dapm_mic ||
1439                        wsource->id == snd_soc_dapm_line ||
1440                        wsource->id == snd_soc_dapm_output)
1441                        wsink->ext = 1;
1442        }
1443        if (wsource->id == snd_soc_dapm_output) {
1444                if (wsink->id == snd_soc_dapm_spk ||
1445                        wsink->id == snd_soc_dapm_hp ||
1446                        wsink->id == snd_soc_dapm_line ||
1447                        wsink->id == snd_soc_dapm_input)
1448                        wsource->ext = 1;
1449        }
1450
1451        /* connect static paths */
1452        if (control == NULL) {
1453                list_add(&path->list, &codec->dapm_paths);
1454                list_add(&path->list_sink, &wsink->sources);
1455                list_add(&path->list_source, &wsource->sinks);
1456                path->connect = 1;
1457                return 0;
1458        }
1459
1460        /* connect dynamic paths */
1461        switch(wsink->id) {
1462        case snd_soc_dapm_adc:
1463        case snd_soc_dapm_dac:
1464        case snd_soc_dapm_pga:
1465        case snd_soc_dapm_input:
1466        case snd_soc_dapm_output:
1467        case snd_soc_dapm_micbias:
1468        case snd_soc_dapm_vmid:
1469        case snd_soc_dapm_pre:
1470        case snd_soc_dapm_post:
1471        case snd_soc_dapm_supply:
1472        case snd_soc_dapm_aif_in:
1473        case snd_soc_dapm_aif_out:
1474                list_add(&path->list, &codec->dapm_paths);
1475                list_add(&path->list_sink, &wsink->sources);
1476                list_add(&path->list_source, &wsource->sinks);
1477                path->connect = 1;
1478                return 0;
1479        case snd_soc_dapm_mux:
1480        case snd_soc_dapm_value_mux:
1481                ret = dapm_connect_mux(codec, wsource, wsink, path, control,
1482                        &wsink->kcontrols[0]);
1483                if (ret != 0)
1484                        goto err;
1485                break;
1486        case snd_soc_dapm_switch:
1487        case snd_soc_dapm_mixer:
1488        case snd_soc_dapm_mixer_named_ctl:
1489                ret = dapm_connect_mixer(codec, wsource, wsink, path, control);
1490                if (ret != 0)
1491                        goto err;
1492                break;
1493        case snd_soc_dapm_hp:
1494        case snd_soc_dapm_mic:
1495        case snd_soc_dapm_line:
1496        case snd_soc_dapm_spk:
1497                list_add(&path->list, &codec->dapm_paths);
1498                list_add(&path->list_sink, &wsink->sources);
1499                list_add(&path->list_source, &wsource->sinks);
1500                path->connect = 0;
1501                return 0;
1502        }
1503        return 0;
1504
1505err:
1506        printk(KERN_WARNING "asoc: no dapm match for %s --> %s --> %s\n", source,
1507                control, sink);
1508        kfree(path);
1509        return ret;
1510}
1511
1512/**
1513 * snd_soc_dapm_add_routes - Add routes between DAPM widgets
1514 * @codec: codec
1515 * @route: audio routes
1516 * @num: number of routes
1517 *
1518 * Connects 2 dapm widgets together via a named audio path. The sink is
1519 * the widget receiving the audio signal, whilst the source is the sender
1520 * of the audio signal.
1521 *
1522 * Returns 0 for success else error. On error all resources can be freed
1523 * with a call to snd_soc_card_free().
1524 */
1525int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
1526                            const struct snd_soc_dapm_route *route, int num)
1527{
1528        int i, ret;
1529
1530        for (i = 0; i < num; i++) {
1531                ret = snd_soc_dapm_add_route(codec, route->sink,
1532                                             route->control, route->source);
1533                if (ret < 0) {
1534                        printk(KERN_ERR "Failed to add route %s->%s\n",
1535                               route->source,
1536                               route->sink);
1537                        return ret;
1538                }
1539                route++;
1540        }
1541
1542        return 0;
1543}
1544EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes);
1545
1546/**
1547 * snd_soc_dapm_new_widgets - add new dapm widgets
1548 * @codec: audio codec
1549 *
1550 * Checks the codec for any new dapm widgets and creates them if found.
1551 *
1552 * Returns 0 for success.
1553 */
1554int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
1555{
1556        struct snd_soc_dapm_widget *w;
1557
1558        list_for_each_entry(w, &codec->dapm_widgets, list)
1559        {
1560                if (w->new)
1561                        continue;
1562
1563                switch(w->id) {
1564                case snd_soc_dapm_switch:
1565                case snd_soc_dapm_mixer:
1566                case snd_soc_dapm_mixer_named_ctl:
1567                        w->power_check = dapm_generic_check_power;
1568                        dapm_new_mixer(codec, w);
1569                        break;
1570                case snd_soc_dapm_mux:
1571                case snd_soc_dapm_value_mux:
1572                        w->power_check = dapm_generic_check_power;
1573                        dapm_new_mux(codec, w);
1574                        break;
1575                case snd_soc_dapm_adc:
1576                case snd_soc_dapm_aif_out:
1577                        w->power_check = dapm_adc_check_power;
1578                        break;
1579                case snd_soc_dapm_dac:
1580                case snd_soc_dapm_aif_in:
1581                        w->power_check = dapm_dac_check_power;
1582                        break;
1583                case snd_soc_dapm_pga:
1584                        w->power_check = dapm_generic_check_power;
1585                        dapm_new_pga(codec, w);
1586                        break;
1587                case snd_soc_dapm_input:
1588                case snd_soc_dapm_output:
1589                case snd_soc_dapm_micbias:
1590                case snd_soc_dapm_spk:
1591                case snd_soc_dapm_hp:
1592                case snd_soc_dapm_mic:
1593                case snd_soc_dapm_line:
1594                        w->power_check = dapm_generic_check_power;
1595                        break;
1596                case snd_soc_dapm_supply:
1597                        w->power_check = dapm_supply_check_power;
1598                case snd_soc_dapm_vmid:
1599                case snd_soc_dapm_pre:
1600                case snd_soc_dapm_post:
1601                        break;
1602                }
1603                w->new = 1;
1604        }
1605
1606        dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP);
1607        return 0;
1608}
1609EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets);
1610
1611/**
1612 * snd_soc_dapm_get_volsw - dapm mixer get callback
1613 * @kcontrol: mixer control
1614 * @ucontrol: control element information
1615 *
1616 * Callback to get the value of a dapm mixer control.
1617 *
1618 * Returns 0 for success.
1619 */
1620int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
1621        struct snd_ctl_elem_value *ucontrol)
1622{
1623        struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1624        struct soc_mixer_control *mc =
1625                (struct soc_mixer_control *)kcontrol->private_value;
1626        unsigned int reg = mc->reg;
1627        unsigned int shift = mc->shift;
1628        unsigned int rshift = mc->rshift;
1629        int max = mc->max;
1630        unsigned int invert = mc->invert;
1631        unsigned int mask = (1 << fls(max)) - 1;
1632
1633        /* return the saved value if we are powered down */
1634        if (widget->id == snd_soc_dapm_pga && !widget->power) {
1635                ucontrol->value.integer.value[0] = widget->saved_value;
1636                return 0;
1637        }
1638
1639        ucontrol->value.integer.value[0] =
1640                (snd_soc_read(widget->codec, reg) >> shift) & mask;
1641        if (shift != rshift)
1642                ucontrol->value.integer.value[1] =
1643                        (snd_soc_read(widget->codec, reg) >> rshift) & mask;
1644        if (invert) {
1645                ucontrol->value.integer.value[0] =
1646                        max - ucontrol->value.integer.value[0];
1647                if (shift != rshift)
1648                        ucontrol->value.integer.value[1] =
1649                                max - ucontrol->value.integer.value[1];
1650        }
1651
1652        return 0;
1653}
1654EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw);
1655
1656/**
1657 * snd_soc_dapm_put_volsw - dapm mixer set callback
1658 * @kcontrol: mixer control
1659 * @ucontrol: control element information
1660 *
1661 * Callback to set the value of a dapm mixer control.
1662 *
1663 * Returns 0 for success.
1664 */
1665int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1666        struct snd_ctl_elem_value *ucontrol)
1667{
1668        struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1669        struct soc_mixer_control *mc =
1670                (struct soc_mixer_control *)kcontrol->private_value;
1671        unsigned int reg = mc->reg;
1672        unsigned int shift = mc->shift;
1673        unsigned int rshift = mc->rshift;
1674        int max = mc->max;
1675        unsigned int mask = (1 << fls(max)) - 1;
1676        unsigned int invert = mc->invert;
1677        unsigned int val, val2, val_mask;
1678        int ret;
1679
1680        val = (ucontrol->value.integer.value[0] & mask);
1681
1682        if (invert)
1683                val = max - val;
1684        val_mask = mask << shift;
1685        val = val << shift;
1686        if (shift != rshift) {
1687                val2 = (ucontrol->value.integer.value[1] & mask);
1688                if (invert)
1689                        val2 = max - val2;
1690                val_mask |= mask << rshift;
1691                val |= val2 << rshift;
1692        }
1693
1694        mutex_lock(&widget->codec->mutex);
1695        widget->value = val;
1696
1697        /* save volume value if the widget is powered down */
1698        if (widget->id == snd_soc_dapm_pga && !widget->power) {
1699                widget->saved_value = val;
1700                mutex_unlock(&widget->codec->mutex);
1701                return 1;
1702        }
1703
1704        dapm_mixer_update_power(widget, kcontrol, reg, val_mask, val, invert);
1705        if (widget->event) {
1706                if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1707                        ret = widget->event(widget, kcontrol,
1708                                                SND_SOC_DAPM_PRE_REG);
1709                        if (ret < 0) {
1710                                ret = 1;
1711                                goto out;
1712                        }
1713                }
1714                ret = snd_soc_update_bits(widget->codec, reg, val_mask, val);
1715                if (widget->event_flags & SND_SOC_DAPM_POST_REG)
1716                        ret = widget->event(widget, kcontrol,
1717                                                SND_SOC_DAPM_POST_REG);
1718        } else
1719                ret = snd_soc_update_bits(widget->codec, reg, val_mask, val);
1720
1721out:
1722        mutex_unlock(&widget->codec->mutex);
1723        return ret;
1724}
1725EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw);
1726
1727/**
1728 * snd_soc_dapm_get_enum_double - dapm enumerated double mixer get callback
1729 * @kcontrol: mixer control
1730 * @ucontrol: control element information
1731 *
1732 * Callback to get the value of a dapm enumerated double mixer control.
1733 *
1734 * Returns 0 for success.
1735 */
1736int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
1737        struct snd_ctl_elem_value *ucontrol)
1738{
1739        struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1740        struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1741        unsigned int val, bitmask;
1742
1743        for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1744                ;
1745        val = snd_soc_read(widget->codec, e->reg);
1746        ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1);
1747        if (e->shift_l != e->shift_r)
1748                ucontrol->value.enumerated.item[1] =
1749                        (val >> e->shift_r) & (bitmask - 1);
1750
1751        return 0;
1752}
1753EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double);
1754
1755/**
1756 * snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback
1757 * @kcontrol: mixer control
1758 * @ucontrol: control element information
1759 *
1760 * Callback to set the value of a dapm enumerated double mixer control.
1761 *
1762 * Returns 0 for success.
1763 */
1764int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1765        struct snd_ctl_elem_value *ucontrol)
1766{
1767        struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1768        struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1769        unsigned int val, mux;
1770        unsigned int mask, bitmask;
1771        int ret = 0;
1772
1773        for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1774                ;
1775        if (ucontrol->value.enumerated.item[0] > e->max - 1)
1776                return -EINVAL;
1777        mux = ucontrol->value.enumerated.item[0];
1778        val = mux << e->shift_l;
1779        mask = (bitmask - 1) << e->shift_l;
1780        if (e->shift_l != e->shift_r) {
1781                if (ucontrol->value.enumerated.item[1] > e->max - 1)
1782                        return -EINVAL;
1783                val |= ucontrol->value.enumerated.item[1] << e->shift_r;
1784                mask |= (bitmask - 1) << e->shift_r;
1785        }
1786
1787        mutex_lock(&widget->codec->mutex);
1788        widget->value = val;
1789        dapm_mux_update_power(widget, kcontrol, mask, mux, val, e);
1790        if (widget->event) {
1791                if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1792                        ret = widget->event(widget,
1793                                kcontrol, SND_SOC_DAPM_PRE_REG);
1794                        if (ret < 0)
1795                                goto out;
1796                }
1797                ret = snd_soc_update_bits(widget->codec, e->reg, mask, val);
1798                if (widget->event_flags & SND_SOC_DAPM_POST_REG)
1799                        ret = widget->event(widget,
1800                                kcontrol, SND_SOC_DAPM_POST_REG);
1801        } else
1802                ret = snd_soc_update_bits(widget->codec, e->reg, mask, val);
1803
1804out:
1805        mutex_unlock(&widget->codec->mutex);
1806        return ret;
1807}
1808EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
1809
1810/**
1811 * snd_soc_dapm_get_value_enum_double - dapm semi enumerated double mixer get
1812 *                                      callback
1813 * @kcontrol: mixer control
1814 * @ucontrol: control element information
1815 *
1816 * Callback to get the value of a dapm semi enumerated double mixer control.
1817 *
1818 * Semi enumerated mixer: the enumerated items are referred as values. Can be
1819 * used for handling bitfield coded enumeration for example.
1820 *
1821 * Returns 0 for success.
1822 */
1823int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol,
1824        struct snd_ctl_elem_value *ucontrol)
1825{
1826        struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1827        struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1828        unsigned int reg_val, val, mux;
1829
1830        reg_val = snd_soc_read(widget->codec, e->reg);
1831        val = (reg_val >> e->shift_l) & e->mask;
1832        for (mux = 0; mux < e->max; mux++) {
1833                if (val == e->values[mux])
1834                        break;
1835        }
1836        ucontrol->value.enumerated.item[0] = mux;
1837        if (e->shift_l != e->shift_r) {
1838                val = (reg_val >> e->shift_r) & e->mask;
1839                for (mux = 0; mux < e->max; mux++) {
1840                        if (val == e->values[mux])
1841                                break;
1842                }
1843                ucontrol->value.enumerated.item[1] = mux;
1844        }
1845
1846        return 0;
1847}
1848EXPORT_SYMBOL_GPL(snd_soc_dapm_get_value_enum_double);
1849
1850/**
1851 * snd_soc_dapm_put_value_enum_double - dapm semi enumerated double mixer set
1852 *                                      callback
1853 * @kcontrol: mixer control
1854 * @ucontrol: control element information
1855 *
1856 * Callback to set the value of a dapm semi enumerated double mixer control.
1857 *
1858 * Semi enumerated mixer: the enumerated items are referred as values. Can be
1859 * used for handling bitfield coded enumeration for example.
1860 *
1861 * Returns 0 for success.
1862 */
1863int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
1864        struct snd_ctl_elem_value *ucontrol)
1865{
1866        struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1867        struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1868        unsigned int val, mux;
1869        unsigned int mask;
1870        int ret = 0;
1871
1872        if (ucontrol->value.enumerated.item[0] > e->max - 1)
1873                return -EINVAL;
1874        mux = ucontrol->value.enumerated.item[0];
1875        val = e->values[ucontrol->value.enumerated.item[0]] << e->shift_l;
1876        mask = e->mask << e->shift_l;
1877        if (e->shift_l != e->shift_r) {
1878                if (ucontrol->value.enumerated.item[1] > e->max - 1)
1879                        return -EINVAL;
1880                val |= e->values[ucontrol->value.enumerated.item[1]] << e->shift_r;
1881                mask |= e->mask << e->shift_r;
1882        }
1883
1884        mutex_lock(&widget->codec->mutex);
1885        widget->value = val;
1886        dapm_mux_update_power(widget, kcontrol, mask, mux, val, e);
1887        if (widget->event) {
1888                if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1889                        ret = widget->event(widget,
1890                                kcontrol, SND_SOC_DAPM_PRE_REG);
1891                        if (ret < 0)
1892                                goto out;
1893                }
1894                ret = snd_soc_update_bits(widget->codec, e->reg, mask, val);
1895                if (widget->event_flags & SND_SOC_DAPM_POST_REG)
1896                        ret = widget->event(widget,
1897                                kcontrol, SND_SOC_DAPM_POST_REG);
1898        } else
1899                ret = snd_soc_update_bits(widget->codec, e->reg, mask, val);
1900
1901out:
1902        mutex_unlock(&widget->codec->mutex);
1903        return ret;
1904}
1905EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double);
1906
1907/**
1908 * snd_soc_dapm_info_pin_switch - Info for a pin switch
1909 *
1910 * @kcontrol: mixer control
1911 * @uinfo: control element information
1912 *
1913 * Callback to provide information about a pin switch control.
1914 */
1915int snd_soc_dapm_info_pin_switch(struct snd_kcontrol *kcontrol,
1916                                 struct snd_ctl_elem_info *uinfo)
1917{
1918        uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1919        uinfo->count = 1;
1920        uinfo->value.integer.min = 0;
1921        uinfo->value.integer.max = 1;
1922
1923        return 0;
1924}
1925EXPORT_SYMBOL_GPL(snd_soc_dapm_info_pin_switch);
1926
1927/**
1928 * snd_soc_dapm_get_pin_switch - Get information for a pin switch
1929 *
1930 * @kcontrol: mixer control
1931 * @ucontrol: Value
1932 */
1933int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
1934                                struct snd_ctl_elem_value *ucontrol)
1935{
1936        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1937        const char *pin = (const char *)kcontrol->private_value;
1938
1939        mutex_lock(&codec->mutex);
1940
1941        ucontrol->value.integer.value[0] =
1942                snd_soc_dapm_get_pin_status(codec, pin);
1943
1944        mutex_unlock(&codec->mutex);
1945
1946        return 0;
1947}
1948EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_switch);
1949
1950/**
1951 * snd_soc_dapm_put_pin_switch - Set information for a pin switch
1952 *
1953 * @kcontrol: mixer control
1954 * @ucontrol: Value
1955 */
1956int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
1957                                struct snd_ctl_elem_value *ucontrol)
1958{
1959        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1960        const char *pin = (const char *)kcontrol->private_value;
1961
1962        mutex_lock(&codec->mutex);
1963
1964        if (ucontrol->value.integer.value[0])
1965                snd_soc_dapm_enable_pin(codec, pin);
1966        else
1967                snd_soc_dapm_disable_pin(codec, pin);
1968
1969        snd_soc_dapm_sync(codec);
1970
1971        mutex_unlock(&codec->mutex);
1972
1973        return 0;
1974}
1975EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch);
1976
1977/**
1978 * snd_soc_dapm_new_control - create new dapm control
1979 * @codec: audio codec
1980 * @widget: widget template
1981 *
1982 * Creates a new dapm control based upon the template.
1983 *
1984 * Returns 0 for success else error.
1985 */
1986int snd_soc_dapm_new_control(struct snd_soc_codec *codec,
1987        const struct snd_soc_dapm_widget *widget)
1988{
1989        struct snd_soc_dapm_widget *w;
1990
1991        if ((w = dapm_cnew_widget(widget)) == NULL)
1992                return -ENOMEM;
1993
1994        w->codec = codec;
1995        INIT_LIST_HEAD(&w->sources);
1996        INIT_LIST_HEAD(&w->sinks);
1997        INIT_LIST_HEAD(&w->list);
1998        list_add(&w->list, &codec->dapm_widgets);
1999
2000        /* machine layer set ups unconnected pins and insertions */
2001        w->connected = 1;
2002        return 0;
2003}
2004EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control);
2005
2006/**
2007 * snd_soc_dapm_new_controls - create new dapm controls
2008 * @codec: audio codec
2009 * @widget: widget array
2010 * @num: number of widgets
2011 *
2012 * Creates new DAPM controls based upon the templates.
2013 *
2014 * Returns 0 for success else error.
2015 */
2016int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
2017        const struct snd_soc_dapm_widget *widget,
2018        int num)
2019{
2020        int i, ret;
2021
2022        for (i = 0; i < num; i++) {
2023                ret = snd_soc_dapm_new_control(codec, widget);
2024                if (ret < 0) {
2025                        printk(KERN_ERR
2026                               "ASoC: Failed to create DAPM control %s: %d\n",
2027                               widget->name, ret);
2028                        return ret;
2029                }
2030                widget++;
2031        }
2032        return 0;
2033}
2034EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
2035
2036
2037/**
2038 * snd_soc_dapm_stream_event - send a stream event to the dapm core
2039 * @codec: audio codec
2040 * @stream: stream name
2041 * @event: stream event
2042 *
2043 * Sends a stream event to the dapm core. The core then makes any
2044 * necessary widget power changes.
2045 *
2046 * Returns 0 for success else error.
2047 */
2048int snd_soc_dapm_stream_event(struct snd_soc_codec *codec,
2049        char *stream, int event)
2050{
2051        struct snd_soc_dapm_widget *w;
2052
2053        if (stream == NULL)
2054                return 0;
2055
2056        mutex_lock(&codec->mutex);
2057        list_for_each_entry(w, &codec->dapm_widgets, list)
2058        {
2059                if (!w->sname)
2060                        continue;
2061                pr_debug("widget %s\n %s stream %s event %d\n",
2062                         w->name, w->sname, stream, event);
2063                if (strstr(w->sname, stream)) {
2064                        switch(event) {
2065                        case SND_SOC_DAPM_STREAM_START:
2066                                w->active = 1;
2067                                break;
2068                        case SND_SOC_DAPM_STREAM_STOP:
2069                                w->active = 0;
2070                                break;
2071                        case SND_SOC_DAPM_STREAM_SUSPEND:
2072                                if (w->active)
2073                                        w->suspend = 1;
2074                                w->active = 0;
2075                                break;
2076                        case SND_SOC_DAPM_STREAM_RESUME:
2077                                if (w->suspend) {
2078                                        w->active = 1;
2079                                        w->suspend = 0;
2080                                }
2081                                break;
2082                        case SND_SOC_DAPM_STREAM_PAUSE_PUSH:
2083                                break;
2084                        case SND_SOC_DAPM_STREAM_PAUSE_RELEASE:
2085                                break;
2086                        }
2087                }
2088        }
2089
2090        dapm_power_widgets(codec, event);
2091        mutex_unlock(&codec->mutex);
2092        dump_dapm(codec, __func__);
2093        return 0;
2094}
2095EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event);
2096
2097/**
2098 * snd_soc_dapm_enable_pin - enable pin.
2099 * @codec: SoC codec
2100 * @pin: pin name
2101 *
2102 * Enables input/output pin and its parents or children widgets iff there is
2103 * a valid audio route and active audio stream.
2104 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
2105 * do any widget power switching.
2106 */
2107int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin)
2108{
2109        return snd_soc_dapm_set_pin(codec, pin, 1);
2110}
2111EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
2112
2113/**
2114 * snd_soc_dapm_disable_pin - disable pin.
2115 * @codec: SoC codec
2116 * @pin: pin name
2117 *
2118 * Disables input/output pin and its parents or children widgets.
2119 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
2120 * do any widget power switching.
2121 */
2122int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, const char *pin)
2123{
2124        return snd_soc_dapm_set_pin(codec, pin, 0);
2125}
2126EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
2127
2128/**
2129 * snd_soc_dapm_nc_pin - permanently disable pin.
2130 * @codec: SoC codec
2131 * @pin: pin name
2132 *
2133 * Marks the specified pin as being not connected, disabling it along
2134 * any parent or child widgets.  At present this is identical to
2135 * snd_soc_dapm_disable_pin() but in future it will be extended to do
2136 * additional things such as disabling controls which only affect
2137 * paths through the pin.
2138 *
2139 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
2140 * do any widget power switching.
2141 */
2142int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin)
2143{
2144        return snd_soc_dapm_set_pin(codec, pin, 0);
2145}
2146EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin);
2147
2148/**
2149 * snd_soc_dapm_get_pin_status - get audio pin status
2150 * @codec: audio codec
2151 * @pin: audio signal pin endpoint (or start point)
2152 *
2153 * Get audio pin status - connected or disconnected.
2154 *
2155 * Returns 1 for connected otherwise 0.
2156 */
2157int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin)
2158{
2159        struct snd_soc_dapm_widget *w;
2160
2161        list_for_each_entry(w, &codec->dapm_widgets, list) {
2162                if (!strcmp(w->name, pin))
2163                        return w->connected;
2164        }
2165
2166        return 0;
2167}
2168EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status);
2169
2170/**
2171 * snd_soc_dapm_free - free dapm resources
2172 * @socdev: SoC device
2173 *
2174 * Free all dapm widgets and resources.
2175 */
2176void snd_soc_dapm_free(struct snd_soc_device *socdev)
2177{
2178        struct snd_soc_codec *codec = socdev->card->codec;
2179
2180        snd_soc_dapm_sys_remove(socdev->dev);
2181        dapm_free_widgets(codec);
2182}
2183EXPORT_SYMBOL_GPL(snd_soc_dapm_free);
2184
2185/*
2186 * snd_soc_dapm_shutdown - callback for system shutdown
2187 */
2188void snd_soc_dapm_shutdown(struct snd_soc_device *socdev)
2189{
2190        struct snd_soc_codec *codec = socdev->card->codec;
2191        struct snd_soc_dapm_widget *w;
2192        LIST_HEAD(down_list);
2193        int powerdown = 0;
2194
2195        list_for_each_entry(w, &codec->dapm_widgets, list) {
2196                if (w->power) {
2197                        dapm_seq_insert(w, &down_list, dapm_down_seq);
2198                        w->power = 0;
2199                        powerdown = 1;
2200                }
2201        }
2202
2203        /* If there were no widgets to power down we're already in
2204         * standby.
2205         */
2206        if (powerdown) {
2207                snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_PREPARE);
2208                dapm_seq_run(codec, &down_list, 0, dapm_down_seq);
2209                snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_STANDBY);
2210        }
2211
2212        snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_OFF);
2213}
2214
2215/* Module information */
2216MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
2217MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC");
2218MODULE_LICENSE("GPL");
2219