linux/drivers/mfd/arizona-core.c
<<
>>
Prefs
   1/*
   2 * Arizona core driver
   3 *
   4 * Copyright 2012 Wolfson Microelectronics plc
   5 *
   6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12
  13#include <linux/delay.h>
  14#include <linux/err.h>
  15#include <linux/gpio.h>
  16#include <linux/interrupt.h>
  17#include <linux/mfd/core.h>
  18#include <linux/module.h>
  19#include <linux/pm_runtime.h>
  20#include <linux/regmap.h>
  21#include <linux/regulator/consumer.h>
  22#include <linux/slab.h>
  23
  24#include <linux/mfd/arizona/core.h>
  25#include <linux/mfd/arizona/registers.h>
  26
  27#include "arizona.h"
  28
  29static const char *wm5102_core_supplies[] = {
  30        "AVDD",
  31        "DBVDD1",
  32};
  33
  34int arizona_clk32k_enable(struct arizona *arizona)
  35{
  36        int ret = 0;
  37
  38        mutex_lock(&arizona->clk_lock);
  39
  40        arizona->clk32k_ref++;
  41
  42        if (arizona->clk32k_ref == 1) {
  43                switch (arizona->pdata.clk32k_src) {
  44                case ARIZONA_32KZ_MCLK1:
  45                        ret = pm_runtime_get_sync(arizona->dev);
  46                        if (ret != 0)
  47                                goto out;
  48                        break;
  49                }
  50
  51                ret = regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
  52                                         ARIZONA_CLK_32K_ENA,
  53                                         ARIZONA_CLK_32K_ENA);
  54        }
  55
  56out:
  57        if (ret != 0)
  58                arizona->clk32k_ref--;
  59
  60        mutex_unlock(&arizona->clk_lock);
  61
  62        return ret;
  63}
  64EXPORT_SYMBOL_GPL(arizona_clk32k_enable);
  65
  66int arizona_clk32k_disable(struct arizona *arizona)
  67{
  68        int ret = 0;
  69
  70        mutex_lock(&arizona->clk_lock);
  71
  72        BUG_ON(arizona->clk32k_ref <= 0);
  73
  74        arizona->clk32k_ref--;
  75
  76        if (arizona->clk32k_ref == 0) {
  77                regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
  78                                   ARIZONA_CLK_32K_ENA, 0);
  79
  80                switch (arizona->pdata.clk32k_src) {
  81                case ARIZONA_32KZ_MCLK1:
  82                        pm_runtime_put_sync(arizona->dev);
  83                        break;
  84                }
  85        }
  86
  87        mutex_unlock(&arizona->clk_lock);
  88
  89        return ret;
  90}
  91EXPORT_SYMBOL_GPL(arizona_clk32k_disable);
  92
  93static irqreturn_t arizona_clkgen_err(int irq, void *data)
  94{
  95        struct arizona *arizona = data;
  96
  97        dev_err(arizona->dev, "CLKGEN error\n");
  98
  99        return IRQ_HANDLED;
 100}
 101
 102static irqreturn_t arizona_underclocked(int irq, void *data)
 103{
 104        struct arizona *arizona = data;
 105        unsigned int val;
 106        int ret;
 107
 108        ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_8,
 109                          &val);
 110        if (ret != 0) {
 111                dev_err(arizona->dev, "Failed to read underclock status: %d\n",
 112                        ret);
 113                return IRQ_NONE;
 114        }
 115
 116        if (val & ARIZONA_AIF3_UNDERCLOCKED_STS)
 117                dev_err(arizona->dev, "AIF3 underclocked\n");
 118        if (val & ARIZONA_AIF2_UNDERCLOCKED_STS)
 119                dev_err(arizona->dev, "AIF2 underclocked\n");
 120        if (val & ARIZONA_AIF1_UNDERCLOCKED_STS)
 121                dev_err(arizona->dev, "AIF1 underclocked\n");
 122        if (val & ARIZONA_ISRC2_UNDERCLOCKED_STS)
 123                dev_err(arizona->dev, "ISRC2 underclocked\n");
 124        if (val & ARIZONA_ISRC1_UNDERCLOCKED_STS)
 125                dev_err(arizona->dev, "ISRC1 underclocked\n");
 126        if (val & ARIZONA_FX_UNDERCLOCKED_STS)
 127                dev_err(arizona->dev, "FX underclocked\n");
 128        if (val & ARIZONA_ASRC_UNDERCLOCKED_STS)
 129                dev_err(arizona->dev, "ASRC underclocked\n");
 130        if (val & ARIZONA_DAC_UNDERCLOCKED_STS)
 131                dev_err(arizona->dev, "DAC underclocked\n");
 132        if (val & ARIZONA_ADC_UNDERCLOCKED_STS)
 133                dev_err(arizona->dev, "ADC underclocked\n");
 134        if (val & ARIZONA_MIXER_UNDERCLOCKED_STS)
 135                dev_err(arizona->dev, "Mixer dropped sample\n");
 136
 137        return IRQ_HANDLED;
 138}
 139
 140static irqreturn_t arizona_overclocked(int irq, void *data)
 141{
 142        struct arizona *arizona = data;
 143        unsigned int val[2];
 144        int ret;
 145        
 146        ret = regmap_bulk_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_6,
 147                               &val[0], 2);
 148        if (ret != 0) {
 149                dev_err(arizona->dev, "Failed to read overclock status: %d\n",
 150                        ret);
 151                return IRQ_NONE;
 152        }
 153
 154        if (val[0] & ARIZONA_PWM_OVERCLOCKED_STS)
 155                dev_err(arizona->dev, "PWM overclocked\n");
 156        if (val[0] & ARIZONA_FX_CORE_OVERCLOCKED_STS)
 157                dev_err(arizona->dev, "FX core overclocked\n");
 158        if (val[0] & ARIZONA_DAC_SYS_OVERCLOCKED_STS)
 159                dev_err(arizona->dev, "DAC SYS overclocked\n");
 160        if (val[0] & ARIZONA_DAC_WARP_OVERCLOCKED_STS)
 161                dev_err(arizona->dev, "DAC WARP overclocked\n");
 162        if (val[0] & ARIZONA_ADC_OVERCLOCKED_STS)
 163                dev_err(arizona->dev, "ADC overclocked\n");
 164        if (val[0] & ARIZONA_MIXER_OVERCLOCKED_STS)
 165                dev_err(arizona->dev, "Mixer overclocked\n");
 166        if (val[0] & ARIZONA_AIF3_SYNC_OVERCLOCKED_STS)
 167                dev_err(arizona->dev, "AIF3 overclocked\n");
 168        if (val[0] & ARIZONA_AIF2_SYNC_OVERCLOCKED_STS)
 169                dev_err(arizona->dev, "AIF2 overclocked\n");
 170        if (val[0] & ARIZONA_AIF1_SYNC_OVERCLOCKED_STS)
 171                dev_err(arizona->dev, "AIF1 overclocked\n");
 172        if (val[0] & ARIZONA_PAD_CTRL_OVERCLOCKED_STS)
 173                dev_err(arizona->dev, "Pad control overclocked\n");
 174
 175        if (val[1] & ARIZONA_SLIMBUS_SUBSYS_OVERCLOCKED_STS)
 176                dev_err(arizona->dev, "Slimbus subsystem overclocked\n");
 177        if (val[1] & ARIZONA_SLIMBUS_ASYNC_OVERCLOCKED_STS)
 178                dev_err(arizona->dev, "Slimbus async overclocked\n");
 179        if (val[1] & ARIZONA_SLIMBUS_SYNC_OVERCLOCKED_STS)
 180                dev_err(arizona->dev, "Slimbus sync overclocked\n");
 181        if (val[1] & ARIZONA_ASRC_ASYNC_SYS_OVERCLOCKED_STS)
 182                dev_err(arizona->dev, "ASRC async system overclocked\n");
 183        if (val[1] & ARIZONA_ASRC_ASYNC_WARP_OVERCLOCKED_STS)
 184                dev_err(arizona->dev, "ASRC async WARP overclocked\n");
 185        if (val[1] & ARIZONA_ASRC_SYNC_SYS_OVERCLOCKED_STS)
 186                dev_err(arizona->dev, "ASRC sync system overclocked\n");
 187        if (val[1] & ARIZONA_ASRC_SYNC_WARP_OVERCLOCKED_STS)
 188                dev_err(arizona->dev, "ASRC sync WARP overclocked\n");
 189        if (val[1] & ARIZONA_ADSP2_1_OVERCLOCKED_STS)
 190                dev_err(arizona->dev, "DSP1 overclocked\n");
 191        if (val[1] & ARIZONA_ISRC2_OVERCLOCKED_STS)
 192                dev_err(arizona->dev, "ISRC2 overclocked\n");
 193        if (val[1] & ARIZONA_ISRC1_OVERCLOCKED_STS)
 194                dev_err(arizona->dev, "ISRC1 overclocked\n");
 195
 196        return IRQ_HANDLED;
 197}
 198
 199static int arizona_poll_reg(struct arizona *arizona,
 200                            int timeout, unsigned int reg,
 201                            unsigned int mask, unsigned int target)
 202{
 203        unsigned int val = 0;
 204        int ret, i;
 205
 206        for (i = 0; i < timeout; i++) {
 207                ret = regmap_read(arizona->regmap, reg, &val);
 208                if (ret != 0) {
 209                        dev_err(arizona->dev, "Failed to read reg %u: %d\n",
 210                                reg, ret);
 211                        continue;
 212                }
 213
 214                if ((val & mask) == target)
 215                        return 0;
 216
 217                msleep(1);
 218        }
 219
 220        dev_err(arizona->dev, "Polling reg %u timed out: %x\n", reg, val);
 221        return -ETIMEDOUT;
 222}
 223
 224static int arizona_wait_for_boot(struct arizona *arizona)
 225{
 226        int ret;
 227
 228        /*
 229         * We can't use an interrupt as we need to runtime resume to do so,
 230         * we won't race with the interrupt handler as it'll be blocked on
 231         * runtime resume.
 232         */
 233        ret = arizona_poll_reg(arizona, 5, ARIZONA_INTERRUPT_RAW_STATUS_5,
 234                               ARIZONA_BOOT_DONE_STS, ARIZONA_BOOT_DONE_STS);
 235
 236        if (!ret)
 237                regmap_write(arizona->regmap, ARIZONA_INTERRUPT_STATUS_5,
 238                             ARIZONA_BOOT_DONE_STS);
 239
 240        pm_runtime_mark_last_busy(arizona->dev);
 241
 242        return ret;
 243}
 244
 245static int arizona_apply_hardware_patch(struct arizona* arizona)
 246{
 247        unsigned int fll, sysclk;
 248        int ret, err;
 249
 250        regcache_cache_bypass(arizona->regmap, true);
 251
 252        /* Cache existing FLL and SYSCLK settings */
 253        ret = regmap_read(arizona->regmap, ARIZONA_FLL1_CONTROL_1, &fll);
 254        if (ret != 0) {
 255                dev_err(arizona->dev, "Failed to cache FLL settings: %d\n",
 256                        ret);
 257                return ret;
 258        }
 259        ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, &sysclk);
 260        if (ret != 0) {
 261                dev_err(arizona->dev, "Failed to cache SYSCLK settings: %d\n",
 262                        ret);
 263                return ret;
 264        }
 265
 266        /* Start up SYSCLK using the FLL in free running mode */
 267        ret = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1,
 268                        ARIZONA_FLL1_ENA | ARIZONA_FLL1_FREERUN);
 269        if (ret != 0) {
 270                dev_err(arizona->dev,
 271                        "Failed to start FLL in freerunning mode: %d\n",
 272                        ret);
 273                return ret;
 274        }
 275        ret = arizona_poll_reg(arizona, 25, ARIZONA_INTERRUPT_RAW_STATUS_5,
 276                               ARIZONA_FLL1_CLOCK_OK_STS,
 277                               ARIZONA_FLL1_CLOCK_OK_STS);
 278        if (ret != 0) {
 279                ret = -ETIMEDOUT;
 280                goto err_fll;
 281        }
 282
 283        ret = regmap_write(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, 0x0144);
 284        if (ret != 0) {
 285                dev_err(arizona->dev, "Failed to start SYSCLK: %d\n", ret);
 286                goto err_fll;
 287        }
 288
 289        /* Start the write sequencer and wait for it to finish */
 290        ret = regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_0,
 291                        ARIZONA_WSEQ_ENA | ARIZONA_WSEQ_START | 160);
 292        if (ret != 0) {
 293                dev_err(arizona->dev, "Failed to start write sequencer: %d\n",
 294                        ret);
 295                goto err_sysclk;
 296        }
 297        ret = arizona_poll_reg(arizona, 5, ARIZONA_WRITE_SEQUENCER_CTRL_1,
 298                               ARIZONA_WSEQ_BUSY, 0);
 299        if (ret != 0) {
 300                regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_0,
 301                                ARIZONA_WSEQ_ABORT);
 302                ret = -ETIMEDOUT;
 303        }
 304
 305err_sysclk:
 306        err = regmap_write(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, sysclk);
 307        if (err != 0) {
 308                dev_err(arizona->dev,
 309                        "Failed to re-apply old SYSCLK settings: %d\n",
 310                        err);
 311        }
 312
 313err_fll:
 314        err = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1, fll);
 315        if (err != 0) {
 316                dev_err(arizona->dev,
 317                        "Failed to re-apply old FLL settings: %d\n",
 318                        err);
 319        }
 320
 321        regcache_cache_bypass(arizona->regmap, false);
 322
 323        if (ret != 0)
 324                return ret;
 325        else
 326                return err;
 327}
 328
 329#ifdef CONFIG_PM_RUNTIME
 330static int arizona_runtime_resume(struct device *dev)
 331{
 332        struct arizona *arizona = dev_get_drvdata(dev);
 333        int ret;
 334
 335        dev_dbg(arizona->dev, "Leaving AoD mode\n");
 336
 337        ret = regulator_enable(arizona->dcvdd);
 338        if (ret != 0) {
 339                dev_err(arizona->dev, "Failed to enable DCVDD: %d\n", ret);
 340                return ret;
 341        }
 342
 343        regcache_cache_only(arizona->regmap, false);
 344
 345        switch (arizona->type) {
 346        case WM5102:
 347                ret = wm5102_patch(arizona);
 348                if (ret != 0) {
 349                        dev_err(arizona->dev, "Failed to apply patch: %d\n",
 350                                ret);
 351                        goto err;
 352                }
 353
 354                ret = arizona_apply_hardware_patch(arizona);
 355                if (ret != 0) {
 356                        dev_err(arizona->dev,
 357                                "Failed to apply hardware patch: %d\n",
 358                                ret);
 359                        goto err;
 360                }
 361                break;
 362        default:
 363                ret = arizona_wait_for_boot(arizona);
 364                if (ret != 0) {
 365                        goto err;
 366                }
 367
 368                break;
 369        }
 370
 371        ret = regcache_sync(arizona->regmap);
 372        if (ret != 0) {
 373                dev_err(arizona->dev, "Failed to restore register cache\n");
 374                goto err;
 375        }
 376
 377        return 0;
 378
 379err:
 380        regcache_cache_only(arizona->regmap, true);
 381        regulator_disable(arizona->dcvdd);
 382        return ret;
 383}
 384
 385static int arizona_runtime_suspend(struct device *dev)
 386{
 387        struct arizona *arizona = dev_get_drvdata(dev);
 388
 389        dev_dbg(arizona->dev, "Entering AoD mode\n");
 390
 391        regulator_disable(arizona->dcvdd);
 392        regcache_cache_only(arizona->regmap, true);
 393        regcache_mark_dirty(arizona->regmap);
 394
 395        return 0;
 396}
 397#endif
 398
 399#ifdef CONFIG_PM_SLEEP
 400static int arizona_resume_noirq(struct device *dev)
 401{
 402        struct arizona *arizona = dev_get_drvdata(dev);
 403
 404        dev_dbg(arizona->dev, "Early resume, disabling IRQ\n");
 405        disable_irq(arizona->irq);
 406
 407        return 0;
 408}
 409
 410static int arizona_resume(struct device *dev)
 411{
 412        struct arizona *arizona = dev_get_drvdata(dev);
 413
 414        dev_dbg(arizona->dev, "Late resume, reenabling IRQ\n");
 415        enable_irq(arizona->irq);
 416
 417        return 0;
 418}
 419#endif
 420
 421const struct dev_pm_ops arizona_pm_ops = {
 422        SET_RUNTIME_PM_OPS(arizona_runtime_suspend,
 423                           arizona_runtime_resume,
 424                           NULL)
 425        SET_SYSTEM_SLEEP_PM_OPS(NULL, arizona_resume)
 426#ifdef CONFIG_PM_SLEEP
 427        .resume_noirq = arizona_resume_noirq,
 428#endif
 429};
 430EXPORT_SYMBOL_GPL(arizona_pm_ops);
 431
 432static struct mfd_cell early_devs[] = {
 433        { .name = "arizona-ldo1" },
 434};
 435
 436static struct mfd_cell wm5102_devs[] = {
 437        { .name = "arizona-micsupp" },
 438        { .name = "arizona-extcon" },
 439        { .name = "arizona-gpio" },
 440        { .name = "arizona-haptics" },
 441        { .name = "arizona-pwm" },
 442        { .name = "wm5102-codec" },
 443};
 444
 445static struct mfd_cell wm5110_devs[] = {
 446        { .name = "arizona-micsupp" },
 447        { .name = "arizona-extcon" },
 448        { .name = "arizona-gpio" },
 449        { .name = "arizona-haptics" },
 450        { .name = "arizona-pwm" },
 451        { .name = "wm5110-codec" },
 452};
 453
 454int arizona_dev_init(struct arizona *arizona)
 455{
 456        struct device *dev = arizona->dev;
 457        const char *type_name;
 458        unsigned int reg, val;
 459        int (*apply_patch)(struct arizona *) = NULL;
 460        int ret, i;
 461
 462        dev_set_drvdata(arizona->dev, arizona);
 463        mutex_init(&arizona->clk_lock);
 464
 465        if (dev_get_platdata(arizona->dev))
 466                memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),
 467                       sizeof(arizona->pdata));
 468
 469        regcache_cache_only(arizona->regmap, true);
 470
 471        switch (arizona->type) {
 472        case WM5102:
 473        case WM5110:
 474                for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++)
 475                        arizona->core_supplies[i].supply
 476                                = wm5102_core_supplies[i];
 477                arizona->num_core_supplies = ARRAY_SIZE(wm5102_core_supplies);
 478                break;
 479        default:
 480                dev_err(arizona->dev, "Unknown device type %d\n",
 481                        arizona->type);
 482                return -EINVAL;
 483        }
 484
 485        ret = mfd_add_devices(arizona->dev, -1, early_devs,
 486                              ARRAY_SIZE(early_devs), NULL, 0, NULL);
 487        if (ret != 0) {
 488                dev_err(dev, "Failed to add early children: %d\n", ret);
 489                return ret;
 490        }
 491
 492        ret = devm_regulator_bulk_get(dev, arizona->num_core_supplies,
 493                                      arizona->core_supplies);
 494        if (ret != 0) {
 495                dev_err(dev, "Failed to request core supplies: %d\n",
 496                        ret);
 497                goto err_early;
 498        }
 499
 500        arizona->dcvdd = devm_regulator_get(arizona->dev, "DCVDD");
 501        if (IS_ERR(arizona->dcvdd)) {
 502                ret = PTR_ERR(arizona->dcvdd);
 503                dev_err(dev, "Failed to request DCVDD: %d\n", ret);
 504                goto err_early;
 505        }
 506
 507        if (arizona->pdata.reset) {
 508                /* Start out with /RESET low to put the chip into reset */
 509                ret = gpio_request_one(arizona->pdata.reset,
 510                                       GPIOF_DIR_OUT | GPIOF_INIT_LOW,
 511                                       "arizona /RESET");
 512                if (ret != 0) {
 513                        dev_err(dev, "Failed to request /RESET: %d\n", ret);
 514                        goto err_early;
 515                }
 516        }
 517
 518        ret = regulator_bulk_enable(arizona->num_core_supplies,
 519                                    arizona->core_supplies);
 520        if (ret != 0) {
 521                dev_err(dev, "Failed to enable core supplies: %d\n",
 522                        ret);
 523                goto err_early;
 524        }
 525
 526        ret = regulator_enable(arizona->dcvdd);
 527        if (ret != 0) {
 528                dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
 529                goto err_enable;
 530        }
 531
 532        if (arizona->pdata.reset) {
 533                gpio_set_value_cansleep(arizona->pdata.reset, 1);
 534                msleep(1);
 535        }
 536
 537        regcache_cache_only(arizona->regmap, false);
 538
 539        ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
 540        if (ret != 0) {
 541                dev_err(dev, "Failed to read ID register: %d\n", ret);
 542                goto err_reset;
 543        }
 544
 545        ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION,
 546                          &arizona->rev);
 547        if (ret != 0) {
 548                dev_err(dev, "Failed to read revision register: %d\n", ret);
 549                goto err_reset;
 550        }
 551        arizona->rev &= ARIZONA_DEVICE_REVISION_MASK;
 552
 553        switch (reg) {
 554#ifdef CONFIG_MFD_WM5102
 555        case 0x5102:
 556                type_name = "WM5102";
 557                if (arizona->type != WM5102) {
 558                        dev_err(arizona->dev, "WM5102 registered as %d\n",
 559                                arizona->type);
 560                        arizona->type = WM5102;
 561                }
 562                apply_patch = wm5102_patch;
 563                arizona->rev &= 0x7;
 564                break;
 565#endif
 566#ifdef CONFIG_MFD_WM5110
 567        case 0x5110:
 568                type_name = "WM5110";
 569                if (arizona->type != WM5110) {
 570                        dev_err(arizona->dev, "WM5110 registered as %d\n",
 571                                arizona->type);
 572                        arizona->type = WM5110;
 573                }
 574                apply_patch = wm5110_patch;
 575                break;
 576#endif
 577        default:
 578                dev_err(arizona->dev, "Unknown device ID %x\n", reg);
 579                goto err_reset;
 580        }
 581
 582        dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');
 583
 584        /* If we have a /RESET GPIO we'll already be reset */
 585        if (!arizona->pdata.reset) {
 586                regcache_mark_dirty(arizona->regmap);
 587
 588                ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0);
 589                if (ret != 0) {
 590                        dev_err(dev, "Failed to reset device: %d\n", ret);
 591                        goto err_reset;
 592                }
 593
 594                msleep(1);
 595
 596                ret = regcache_sync(arizona->regmap);
 597                if (ret != 0) {
 598                        dev_err(dev, "Failed to sync device: %d\n", ret);
 599                        goto err_reset;
 600                }
 601        }
 602
 603        switch (arizona->type) {
 604        case WM5102:
 605                ret = regmap_read(arizona->regmap, 0x19, &val);
 606                if (ret != 0)
 607                        dev_err(dev,
 608                                "Failed to check write sequencer state: %d\n",
 609                                ret);
 610                else if (val & 0x01)
 611                        break;
 612                /* Fall through */
 613        default:
 614                ret = arizona_wait_for_boot(arizona);
 615                if (ret != 0) {
 616                        dev_err(arizona->dev,
 617                                "Device failed initial boot: %d\n", ret);
 618                        goto err_reset;
 619                }
 620                break;
 621        }
 622
 623        if (apply_patch) {
 624                ret = apply_patch(arizona);
 625                if (ret != 0) {
 626                        dev_err(arizona->dev, "Failed to apply patch: %d\n",
 627                                ret);
 628                        goto err_reset;
 629                }
 630
 631                switch (arizona->type) {
 632                case WM5102:
 633                        ret = arizona_apply_hardware_patch(arizona);
 634                        if (ret != 0) {
 635                                dev_err(arizona->dev,
 636                                        "Failed to apply hardware patch: %d\n",
 637                                        ret);
 638                                goto err_reset;
 639                        }
 640                        break;
 641                default:
 642                        break;
 643                }
 644        }
 645
 646        for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
 647                if (!arizona->pdata.gpio_defaults[i])
 648                        continue;
 649
 650                regmap_write(arizona->regmap, ARIZONA_GPIO1_CTRL + i,
 651                             arizona->pdata.gpio_defaults[i]);
 652        }
 653
 654        pm_runtime_set_autosuspend_delay(arizona->dev, 100);
 655        pm_runtime_use_autosuspend(arizona->dev);
 656        pm_runtime_enable(arizona->dev);
 657
 658        /* Chip default */
 659        if (!arizona->pdata.clk32k_src)
 660                arizona->pdata.clk32k_src = ARIZONA_32KZ_MCLK2;
 661
 662        switch (arizona->pdata.clk32k_src) {
 663        case ARIZONA_32KZ_MCLK1:
 664        case ARIZONA_32KZ_MCLK2:
 665                regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
 666                                   ARIZONA_CLK_32K_SRC_MASK,
 667                                   arizona->pdata.clk32k_src - 1);
 668                arizona_clk32k_enable(arizona);
 669                break;
 670        case ARIZONA_32KZ_NONE:
 671                regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1,
 672                                   ARIZONA_CLK_32K_SRC_MASK, 2);
 673                break;
 674        default:
 675                dev_err(arizona->dev, "Invalid 32kHz clock source: %d\n",
 676                        arizona->pdata.clk32k_src);
 677                ret = -EINVAL;
 678                goto err_reset;
 679        }
 680
 681        for (i = 0; i < ARIZONA_MAX_MICBIAS; i++) {
 682                if (!arizona->pdata.micbias[i].mV &&
 683                    !arizona->pdata.micbias[i].bypass)
 684                        continue;
 685
 686                /* Apply default for bypass mode */
 687                if (!arizona->pdata.micbias[i].mV)
 688                        arizona->pdata.micbias[i].mV = 2800;
 689
 690                val = (arizona->pdata.micbias[i].mV - 1500) / 100;
 691
 692                val <<= ARIZONA_MICB1_LVL_SHIFT;
 693
 694                if (arizona->pdata.micbias[i].ext_cap)
 695                        val |= ARIZONA_MICB1_EXT_CAP;
 696
 697                if (arizona->pdata.micbias[i].discharge)
 698                        val |= ARIZONA_MICB1_DISCH;
 699
 700                if (arizona->pdata.micbias[i].fast_start)
 701                        val |= ARIZONA_MICB1_RATE;
 702
 703                if (arizona->pdata.micbias[i].bypass)
 704                        val |= ARIZONA_MICB1_BYPASS;
 705
 706                regmap_update_bits(arizona->regmap,
 707                                   ARIZONA_MIC_BIAS_CTRL_1 + i,
 708                                   ARIZONA_MICB1_LVL_MASK |
 709                                   ARIZONA_MICB1_DISCH |
 710                                   ARIZONA_MICB1_BYPASS |
 711                                   ARIZONA_MICB1_RATE, val);
 712        }
 713
 714        for (i = 0; i < ARIZONA_MAX_INPUT; i++) {
 715                /* Default for both is 0 so noop with defaults */
 716                val = arizona->pdata.dmic_ref[i]
 717                        << ARIZONA_IN1_DMIC_SUP_SHIFT;
 718                val |= arizona->pdata.inmode[i] << ARIZONA_IN1_MODE_SHIFT;
 719
 720                regmap_update_bits(arizona->regmap,
 721                                   ARIZONA_IN1L_CONTROL + (i * 8),
 722                                   ARIZONA_IN1_DMIC_SUP_MASK |
 723                                   ARIZONA_IN1_MODE_MASK, val);
 724        }
 725
 726        for (i = 0; i < ARIZONA_MAX_OUTPUT; i++) {
 727                /* Default is 0 so noop with defaults */
 728                if (arizona->pdata.out_mono[i])
 729                        val = ARIZONA_OUT1_MONO;
 730                else
 731                        val = 0;
 732
 733                regmap_update_bits(arizona->regmap,
 734                                   ARIZONA_OUTPUT_PATH_CONFIG_1L + (i * 8),
 735                                   ARIZONA_OUT1_MONO, val);
 736        }
 737
 738        for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) {
 739                if (arizona->pdata.spk_mute[i])
 740                        regmap_update_bits(arizona->regmap,
 741                                           ARIZONA_PDM_SPK1_CTRL_1 + (i * 2),
 742                                           ARIZONA_SPK1_MUTE_ENDIAN_MASK |
 743                                           ARIZONA_SPK1_MUTE_SEQ1_MASK,
 744                                           arizona->pdata.spk_mute[i]);
 745
 746                if (arizona->pdata.spk_fmt[i])
 747                        regmap_update_bits(arizona->regmap,
 748                                           ARIZONA_PDM_SPK1_CTRL_2 + (i * 2),
 749                                           ARIZONA_SPK1_FMT_MASK,
 750                                           arizona->pdata.spk_fmt[i]);
 751        }
 752
 753        /* Set up for interrupts */
 754        ret = arizona_irq_init(arizona);
 755        if (ret != 0)
 756                goto err_reset;
 757
 758        arizona_request_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, "CLKGEN error",
 759                            arizona_clkgen_err, arizona);
 760        arizona_request_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, "Overclocked",
 761                            arizona_overclocked, arizona);
 762        arizona_request_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, "Underclocked",
 763                            arizona_underclocked, arizona);
 764
 765        switch (arizona->type) {
 766        case WM5102:
 767                ret = mfd_add_devices(arizona->dev, -1, wm5102_devs,
 768                                      ARRAY_SIZE(wm5102_devs), NULL, 0, NULL);
 769                break;
 770        case WM5110:
 771                ret = mfd_add_devices(arizona->dev, -1, wm5110_devs,
 772                                      ARRAY_SIZE(wm5110_devs), NULL, 0, NULL);
 773                break;
 774        }
 775
 776        if (ret != 0) {
 777                dev_err(arizona->dev, "Failed to add subdevices: %d\n", ret);
 778                goto err_irq;
 779        }
 780
 781#ifdef CONFIG_PM_RUNTIME
 782        regulator_disable(arizona->dcvdd);
 783#endif
 784
 785        return 0;
 786
 787err_irq:
 788        arizona_irq_exit(arizona);
 789err_reset:
 790        if (arizona->pdata.reset) {
 791                gpio_set_value_cansleep(arizona->pdata.reset, 0);
 792                gpio_free(arizona->pdata.reset);
 793        }
 794        regulator_disable(arizona->dcvdd);
 795err_enable:
 796        regulator_bulk_disable(arizona->num_core_supplies,
 797                               arizona->core_supplies);
 798err_early:
 799        mfd_remove_devices(dev);
 800        return ret;
 801}
 802EXPORT_SYMBOL_GPL(arizona_dev_init);
 803
 804int arizona_dev_exit(struct arizona *arizona)
 805{
 806        mfd_remove_devices(arizona->dev);
 807        arizona_free_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, arizona);
 808        arizona_free_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, arizona);
 809        arizona_free_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, arizona);
 810        pm_runtime_disable(arizona->dev);
 811        arizona_irq_exit(arizona);
 812        return 0;
 813}
 814EXPORT_SYMBOL_GPL(arizona_dev_exit);
 815
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.