linux/drivers/mfd/madera-core.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Core MFD support for Cirrus Logic Madera codecs
   4 *
   5 * Copyright (C) 2015-2018 Cirrus Logic
   6 */
   7
   8#include <linux/device.h>
   9#include <linux/delay.h>
  10#include <linux/err.h>
  11#include <linux/gpio.h>
  12#include <linux/mfd/core.h>
  13#include <linux/module.h>
  14#include <linux/mutex.h>
  15#include <linux/notifier.h>
  16#include <linux/of.h>
  17#include <linux/of_gpio.h>
  18#include <linux/platform_device.h>
  19#include <linux/pm_runtime.h>
  20#include <linux/regmap.h>
  21#include <linux/regulator/consumer.h>
  22#include <linux/regulator/machine.h>
  23#include <linux/regulator/of_regulator.h>
  24
  25#include <linux/mfd/madera/core.h>
  26#include <linux/mfd/madera/registers.h>
  27
  28#include "madera.h"
  29
  30#define CS47L15_SILICON_ID      0x6370
  31#define CS47L35_SILICON_ID      0x6360
  32#define CS47L85_SILICON_ID      0x6338
  33#define CS47L90_SILICON_ID      0x6364
  34#define CS47L92_SILICON_ID      0x6371
  35
  36#define MADERA_32KZ_MCLK2       1
  37
  38#define MADERA_RESET_MIN_US     2000
  39#define MADERA_RESET_MAX_US     3000
  40
  41#define ERRATA_DCVDD_MIN_US     10000
  42#define ERRATA_DCVDD_MAX_US     15000
  43
  44static const char * const madera_core_supplies[] = {
  45        "AVDD",
  46        "DBVDD1",
  47};
  48
  49static const struct mfd_cell madera_ldo1_devs[] = {
  50        {
  51                .name = "madera-ldo1",
  52                .level = MFD_DEP_LEVEL_HIGH,
  53        },
  54};
  55
  56static const char * const cs47l15_supplies[] = {
  57        "MICVDD",
  58        "CPVDD1",
  59        "SPKVDD",
  60};
  61
  62static const struct mfd_cell cs47l15_devs[] = {
  63        { .name = "madera-pinctrl", },
  64        { .name = "madera-irq", },
  65        { .name = "madera-gpio", },
  66        {
  67                .name = "madera-extcon",
  68                .parent_supplies = cs47l15_supplies,
  69                .num_parent_supplies = 1, /* We only need MICVDD */
  70        },
  71        {
  72                .name = "cs47l15-codec",
  73                .parent_supplies = cs47l15_supplies,
  74                .num_parent_supplies = ARRAY_SIZE(cs47l15_supplies),
  75        },
  76};
  77
  78static const char * const cs47l35_supplies[] = {
  79        "MICVDD",
  80        "DBVDD2",
  81        "CPVDD1",
  82        "CPVDD2",
  83        "SPKVDD",
  84};
  85
  86static const struct mfd_cell cs47l35_devs[] = {
  87        { .name = "madera-pinctrl", },
  88        { .name = "madera-irq", },
  89        { .name = "madera-micsupp", },
  90        { .name = "madera-gpio", },
  91        {
  92                .name = "madera-extcon",
  93                .parent_supplies = cs47l35_supplies,
  94                .num_parent_supplies = 1, /* We only need MICVDD */
  95        },
  96        {
  97                .name = "cs47l35-codec",
  98                .parent_supplies = cs47l35_supplies,
  99                .num_parent_supplies = ARRAY_SIZE(cs47l35_supplies),
 100        },
 101};
 102
 103static const char * const cs47l85_supplies[] = {
 104        "MICVDD",
 105        "DBVDD2",
 106        "DBVDD3",
 107        "DBVDD4",
 108        "CPVDD1",
 109        "CPVDD2",
 110        "SPKVDDL",
 111        "SPKVDDR",
 112};
 113
 114static const struct mfd_cell cs47l85_devs[] = {
 115        { .name = "madera-pinctrl", },
 116        { .name = "madera-irq", },
 117        { .name = "madera-micsupp", },
 118        { .name = "madera-gpio", },
 119        {
 120                .name = "madera-extcon",
 121                .parent_supplies = cs47l85_supplies,
 122                .num_parent_supplies = 1, /* We only need MICVDD */
 123        },
 124        {
 125                .name = "cs47l85-codec",
 126                .parent_supplies = cs47l85_supplies,
 127                .num_parent_supplies = ARRAY_SIZE(cs47l85_supplies),
 128        },
 129};
 130
 131static const char * const cs47l90_supplies[] = {
 132        "MICVDD",
 133        "DBVDD2",
 134        "DBVDD3",
 135        "DBVDD4",
 136        "CPVDD1",
 137        "CPVDD2",
 138};
 139
 140static const struct mfd_cell cs47l90_devs[] = {
 141        { .name = "madera-pinctrl", },
 142        { .name = "madera-irq", },
 143        { .name = "madera-micsupp", },
 144        { .name = "madera-gpio", },
 145        {
 146                .name = "madera-extcon",
 147                .parent_supplies = cs47l90_supplies,
 148                .num_parent_supplies = 1, /* We only need MICVDD */
 149        },
 150        {
 151                .name = "cs47l90-codec",
 152                .parent_supplies = cs47l90_supplies,
 153                .num_parent_supplies = ARRAY_SIZE(cs47l90_supplies),
 154        },
 155};
 156
 157static const char * const cs47l92_supplies[] = {
 158        "MICVDD",
 159        "CPVDD1",
 160        "CPVDD2",
 161};
 162
 163static const struct mfd_cell cs47l92_devs[] = {
 164        { .name = "madera-pinctrl", },
 165        { .name = "madera-irq", },
 166        { .name = "madera-micsupp", },
 167        { .name = "madera-gpio", },
 168        {
 169                .name = "madera-extcon",
 170                .parent_supplies = cs47l92_supplies,
 171                .num_parent_supplies = 1, /* We only need MICVDD */
 172        },
 173        {
 174                .name = "cs47l92-codec",
 175                .parent_supplies = cs47l92_supplies,
 176                .num_parent_supplies = ARRAY_SIZE(cs47l92_supplies),
 177        },
 178};
 179
 180/* Used by madera-i2c and madera-spi drivers */
 181const char *madera_name_from_type(enum madera_type type)
 182{
 183        switch (type) {
 184        case CS47L15:
 185                return "CS47L15";
 186        case CS47L35:
 187                return "CS47L35";
 188        case CS47L85:
 189                return "CS47L85";
 190        case CS47L90:
 191                return "CS47L90";
 192        case CS47L91:
 193                return "CS47L91";
 194        case CS42L92:
 195                return "CS42L92";
 196        case CS47L92:
 197                return "CS47L92";
 198        case CS47L93:
 199                return "CS47L93";
 200        case WM1840:
 201                return "WM1840";
 202        default:
 203                return "Unknown";
 204        }
 205}
 206EXPORT_SYMBOL_GPL(madera_name_from_type);
 207
 208#define MADERA_BOOT_POLL_INTERVAL_USEC          5000
 209#define MADERA_BOOT_POLL_TIMEOUT_USEC           25000
 210
 211static int madera_wait_for_boot_noack(struct madera *madera)
 212{
 213        ktime_t timeout;
 214        unsigned int val = 0;
 215        int ret = 0;
 216
 217        /*
 218         * We can't use an interrupt as we need to runtime resume to do so,
 219         * so we poll the status bit. This won't race with the interrupt
 220         * handler because it will be blocked on runtime resume.
 221         * The chip could NAK a read request while it is booting so ignore
 222         * errors from regmap_read.
 223         */
 224        timeout = ktime_add_us(ktime_get(), MADERA_BOOT_POLL_TIMEOUT_USEC);
 225        regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_1, &val);
 226        while (!(val & MADERA_BOOT_DONE_STS1) &&
 227               !ktime_after(ktime_get(), timeout)) {
 228                usleep_range(MADERA_BOOT_POLL_INTERVAL_USEC / 2,
 229                             MADERA_BOOT_POLL_INTERVAL_USEC);
 230                regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_1, &val);
 231        }
 232
 233        if (!(val & MADERA_BOOT_DONE_STS1)) {
 234                dev_err(madera->dev, "Polling BOOT_DONE_STS timed out\n");
 235                ret = -ETIMEDOUT;
 236        }
 237
 238        return ret;
 239}
 240
 241static int madera_wait_for_boot(struct madera *madera)
 242{
 243        int ret = madera_wait_for_boot_noack(madera);
 244
 245        /*
 246         * BOOT_DONE defaults to unmasked on boot so we must ack it.
 247         * Do this even after a timeout to avoid interrupt storms.
 248         */
 249        regmap_write(madera->regmap, MADERA_IRQ1_STATUS_1,
 250                     MADERA_BOOT_DONE_EINT1);
 251
 252        pm_runtime_mark_last_busy(madera->dev);
 253
 254        return ret;
 255}
 256
 257static int madera_soft_reset(struct madera *madera)
 258{
 259        int ret;
 260
 261        ret = regmap_write(madera->regmap, MADERA_SOFTWARE_RESET, 0);
 262        if (ret != 0) {
 263                dev_err(madera->dev, "Failed to soft reset device: %d\n", ret);
 264                return ret;
 265        }
 266
 267        /* Allow time for internal clocks to startup after reset */
 268        usleep_range(MADERA_RESET_MIN_US, MADERA_RESET_MAX_US);
 269
 270        return 0;
 271}
 272
 273static void madera_enable_hard_reset(struct madera *madera)
 274{
 275        /*
 276         * There are many existing out-of-tree users of these codecs that we
 277         * can't break so preserve the expected behaviour of setting the line
 278         * low to assert reset.
 279         */
 280        gpiod_set_raw_value_cansleep(madera->pdata.reset, 0);
 281}
 282
 283static void madera_disable_hard_reset(struct madera *madera)
 284{
 285        gpiod_set_raw_value_cansleep(madera->pdata.reset, 1);
 286
 287        usleep_range(MADERA_RESET_MIN_US, MADERA_RESET_MAX_US);
 288}
 289
 290static int __maybe_unused madera_runtime_resume(struct device *dev)
 291{
 292        struct madera *madera = dev_get_drvdata(dev);
 293        int ret;
 294
 295        dev_dbg(dev, "Leaving sleep mode\n");
 296
 297        if (!madera->reset_errata)
 298                madera_enable_hard_reset(madera);
 299
 300        ret = regulator_enable(madera->dcvdd);
 301        if (ret) {
 302                dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
 303                return ret;
 304        }
 305
 306        regcache_cache_only(madera->regmap, false);
 307        regcache_cache_only(madera->regmap_32bit, false);
 308
 309        if (madera->reset_errata)
 310                usleep_range(ERRATA_DCVDD_MIN_US, ERRATA_DCVDD_MAX_US);
 311        else
 312                madera_disable_hard_reset(madera);
 313
 314        if (!madera->pdata.reset || madera->reset_errata) {
 315                ret = madera_wait_for_boot(madera);
 316                if (ret)
 317                        goto err;
 318
 319                ret = madera_soft_reset(madera);
 320                if (ret) {
 321                        dev_err(dev, "Failed to reset: %d\n", ret);
 322                        goto err;
 323                }
 324        }
 325
 326        ret = madera_wait_for_boot(madera);
 327        if (ret)
 328                goto err;
 329
 330        ret = regcache_sync(madera->regmap);
 331        if (ret) {
 332                dev_err(dev, "Failed to restore 16-bit register cache\n");
 333                goto err;
 334        }
 335
 336        ret = regcache_sync(madera->regmap_32bit);
 337        if (ret) {
 338                dev_err(dev, "Failed to restore 32-bit register cache\n");
 339                goto err;
 340        }
 341
 342        return 0;
 343
 344err:
 345        regcache_cache_only(madera->regmap_32bit, true);
 346        regcache_cache_only(madera->regmap, true);
 347        regulator_disable(madera->dcvdd);
 348
 349        return ret;
 350}
 351
 352static int __maybe_unused madera_runtime_suspend(struct device *dev)
 353{
 354        struct madera *madera = dev_get_drvdata(dev);
 355
 356        dev_dbg(madera->dev, "Entering sleep mode\n");
 357
 358        regcache_cache_only(madera->regmap, true);
 359        regcache_mark_dirty(madera->regmap);
 360        regcache_cache_only(madera->regmap_32bit, true);
 361        regcache_mark_dirty(madera->regmap_32bit);
 362
 363        regulator_disable(madera->dcvdd);
 364
 365        return 0;
 366}
 367
 368const struct dev_pm_ops madera_pm_ops = {
 369        SET_RUNTIME_PM_OPS(madera_runtime_suspend,
 370                           madera_runtime_resume,
 371                           NULL)
 372};
 373EXPORT_SYMBOL_GPL(madera_pm_ops);
 374
 375const struct of_device_id madera_of_match[] = {
 376        { .compatible = "cirrus,cs47l15", .data = (void *)CS47L15 },
 377        { .compatible = "cirrus,cs47l35", .data = (void *)CS47L35 },
 378        { .compatible = "cirrus,cs47l85", .data = (void *)CS47L85 },
 379        { .compatible = "cirrus,cs47l90", .data = (void *)CS47L90 },
 380        { .compatible = "cirrus,cs47l91", .data = (void *)CS47L91 },
 381        { .compatible = "cirrus,cs42l92", .data = (void *)CS42L92 },
 382        { .compatible = "cirrus,cs47l92", .data = (void *)CS47L92 },
 383        { .compatible = "cirrus,cs47l93", .data = (void *)CS47L93 },
 384        { .compatible = "cirrus,wm1840", .data = (void *)WM1840 },
 385        {}
 386};
 387MODULE_DEVICE_TABLE(of, madera_of_match);
 388EXPORT_SYMBOL_GPL(madera_of_match);
 389
 390static int madera_get_reset_gpio(struct madera *madera)
 391{
 392        struct gpio_desc *reset;
 393
 394        if (madera->pdata.reset)
 395                return 0;
 396
 397        reset = devm_gpiod_get_optional(madera->dev, "reset", GPIOD_OUT_LOW);
 398        if (IS_ERR(reset))
 399                return dev_err_probe(madera->dev, PTR_ERR(reset),
 400                                "Failed to request /RESET");
 401
 402        /*
 403         * A hard reset is needed for full reset of the chip. We allow running
 404         * without hard reset only because it can be useful for early
 405         * prototyping and some debugging, but we need to warn it's not ideal.
 406         */
 407        if (!reset)
 408                dev_warn(madera->dev,
 409                         "Running without reset GPIO is not recommended\n");
 410
 411        madera->pdata.reset = reset;
 412
 413        return 0;
 414}
 415
 416static void madera_set_micbias_info(struct madera *madera)
 417{
 418        /*
 419         * num_childbias is an array because future codecs can have different
 420         * childbiases for each micbias. Unspecified values default to 0.
 421         */
 422        switch (madera->type) {
 423        case CS47L15:
 424                madera->num_micbias = 1;
 425                madera->num_childbias[0] = 3;
 426                return;
 427        case CS47L35:
 428                madera->num_micbias = 2;
 429                madera->num_childbias[0] = 2;
 430                madera->num_childbias[1] = 2;
 431                return;
 432        case CS47L85:
 433        case WM1840:
 434                madera->num_micbias = 4;
 435                /* no child biases */
 436                return;
 437        case CS47L90:
 438        case CS47L91:
 439                madera->num_micbias = 2;
 440                madera->num_childbias[0] = 4;
 441                madera->num_childbias[1] = 4;
 442                return;
 443        case CS42L92:
 444        case CS47L92:
 445        case CS47L93:
 446                madera->num_micbias = 2;
 447                madera->num_childbias[0] = 4;
 448                madera->num_childbias[1] = 2;
 449                return;
 450        default:
 451                return;
 452        }
 453}
 454
 455int madera_dev_init(struct madera *madera)
 456{
 457        struct device *dev = madera->dev;
 458        unsigned int hwid;
 459        int (*patch_fn)(struct madera *) = NULL;
 460        const struct mfd_cell *mfd_devs;
 461        int n_devs = 0;
 462        int i, ret;
 463
 464        dev_set_drvdata(madera->dev, madera);
 465        BLOCKING_INIT_NOTIFIER_HEAD(&madera->notifier);
 466        mutex_init(&madera->dapm_ptr_lock);
 467
 468        madera_set_micbias_info(madera);
 469
 470        /*
 471         * We need writable hw config info that all children can share.
 472         * Simplest to take one shared copy of pdata struct.
 473         */
 474        if (dev_get_platdata(madera->dev)) {
 475                memcpy(&madera->pdata, dev_get_platdata(madera->dev),
 476                       sizeof(madera->pdata));
 477        }
 478
 479        madera->mclk[MADERA_MCLK1].id = "mclk1";
 480        madera->mclk[MADERA_MCLK2].id = "mclk2";
 481        madera->mclk[MADERA_MCLK3].id = "mclk3";
 482
 483        ret = devm_clk_bulk_get_optional(madera->dev, ARRAY_SIZE(madera->mclk),
 484                                         madera->mclk);
 485        if (ret) {
 486                dev_err(madera->dev, "Failed to get clocks: %d\n", ret);
 487                return ret;
 488        }
 489
 490        /* Not using devm_clk_get to prevent breakage of existing DTs */
 491        if (!madera->mclk[MADERA_MCLK2].clk)
 492                dev_warn(madera->dev, "Missing MCLK2, requires 32kHz clock\n");
 493
 494        ret = madera_get_reset_gpio(madera);
 495        if (ret)
 496                return ret;
 497
 498        regcache_cache_only(madera->regmap, true);
 499        regcache_cache_only(madera->regmap_32bit, true);
 500
 501        for (i = 0; i < ARRAY_SIZE(madera_core_supplies); i++)
 502                madera->core_supplies[i].supply = madera_core_supplies[i];
 503
 504        madera->num_core_supplies = ARRAY_SIZE(madera_core_supplies);
 505
 506        /*
 507         * On some codecs DCVDD could be supplied by the internal LDO1.
 508         * For those we must add the LDO1 driver before requesting DCVDD
 509         * No devm_ because we need to control shutdown order of children.
 510         */
 511        switch (madera->type) {
 512        case CS47L15:
 513                madera->reset_errata = true;
 514                break;
 515        case CS47L35:
 516        case CS47L90:
 517        case CS47L91:
 518        case CS42L92:
 519        case CS47L92:
 520        case CS47L93:
 521                break;
 522        case CS47L85:
 523        case WM1840:
 524                ret = mfd_add_devices(madera->dev, PLATFORM_DEVID_NONE,
 525                                      madera_ldo1_devs,
 526                                      ARRAY_SIZE(madera_ldo1_devs),
 527                                      NULL, 0, NULL);
 528                if (ret) {
 529                        dev_err(dev, "Failed to add LDO1 child: %d\n", ret);
 530                        return ret;
 531                }
 532                break;
 533        default:
 534                /* No point continuing if the type is unknown */
 535                dev_err(madera->dev, "Unknown device type %d\n", madera->type);
 536                return -ENODEV;
 537        }
 538
 539        ret = devm_regulator_bulk_get(dev, madera->num_core_supplies,
 540                                      madera->core_supplies);
 541        if (ret) {
 542                dev_err(dev, "Failed to request core supplies: %d\n", ret);
 543                goto err_devs;
 544        }
 545
 546        /*
 547         * Don't use devres here. If the regulator is one of our children it
 548         * will already have been removed before devres cleanup on this mfd
 549         * driver tries to call put() on it. We need control of shutdown order.
 550         */
 551        madera->dcvdd = regulator_get(madera->dev, "DCVDD");
 552        if (IS_ERR(madera->dcvdd)) {
 553                ret = PTR_ERR(madera->dcvdd);
 554                dev_err(dev, "Failed to request DCVDD: %d\n", ret);
 555                goto err_devs;
 556        }
 557
 558        ret = regulator_bulk_enable(madera->num_core_supplies,
 559                                    madera->core_supplies);
 560        if (ret) {
 561                dev_err(dev, "Failed to enable core supplies: %d\n", ret);
 562                goto err_dcvdd;
 563        }
 564
 565        if (madera->reset_errata)
 566                madera_disable_hard_reset(madera);
 567
 568        ret = regulator_enable(madera->dcvdd);
 569        if (ret) {
 570                dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
 571                goto err_enable;
 572        }
 573
 574        if (madera->reset_errata)
 575                usleep_range(ERRATA_DCVDD_MIN_US, ERRATA_DCVDD_MAX_US);
 576        else
 577                madera_disable_hard_reset(madera);
 578
 579        regcache_cache_only(madera->regmap, false);
 580        regcache_cache_only(madera->regmap_32bit, false);
 581
 582        ret = madera_wait_for_boot_noack(madera);
 583        if (ret) {
 584                dev_err(madera->dev, "Device failed initial boot: %d\n", ret);
 585                goto err_reset;
 586        }
 587
 588        /*
 589         * Now we can power up and verify that this is a chip we know about
 590         * before we start doing any writes to its registers.
 591         */
 592        ret = regmap_read(madera->regmap, MADERA_SOFTWARE_RESET, &hwid);
 593        if (ret) {
 594                dev_err(dev, "Failed to read ID register: %d\n", ret);
 595                goto err_reset;
 596        }
 597
 598        switch (hwid) {
 599        case CS47L15_SILICON_ID:
 600                if (IS_ENABLED(CONFIG_MFD_CS47L15)) {
 601                        switch (madera->type) {
 602                        case CS47L15:
 603                                patch_fn = &cs47l15_patch;
 604                                mfd_devs = cs47l15_devs;
 605                                n_devs = ARRAY_SIZE(cs47l15_devs);
 606                                break;
 607                        default:
 608                                break;
 609                        }
 610                }
 611                break;
 612        case CS47L35_SILICON_ID:
 613                if (IS_ENABLED(CONFIG_MFD_CS47L35)) {
 614                        switch (madera->type) {
 615                        case CS47L35:
 616                                patch_fn = cs47l35_patch;
 617                                mfd_devs = cs47l35_devs;
 618                                n_devs = ARRAY_SIZE(cs47l35_devs);
 619                                break;
 620                        default:
 621                                break;
 622                        }
 623                }
 624                break;
 625        case CS47L85_SILICON_ID:
 626                if (IS_ENABLED(CONFIG_MFD_CS47L85)) {
 627                        switch (madera->type) {
 628                        case CS47L85:
 629                        case WM1840:
 630                                patch_fn = cs47l85_patch;
 631                                mfd_devs = cs47l85_devs;
 632                                n_devs = ARRAY_SIZE(cs47l85_devs);
 633                                break;
 634                        default:
 635                                break;
 636                        }
 637                }
 638                break;
 639        case CS47L90_SILICON_ID:
 640                if (IS_ENABLED(CONFIG_MFD_CS47L90)) {
 641                        switch (madera->type) {
 642                        case CS47L90:
 643                        case CS47L91:
 644                                patch_fn = cs47l90_patch;
 645                                mfd_devs = cs47l90_devs;
 646                                n_devs = ARRAY_SIZE(cs47l90_devs);
 647                                break;
 648                        default:
 649                                break;
 650                        }
 651                }
 652                break;
 653        case CS47L92_SILICON_ID:
 654                if (IS_ENABLED(CONFIG_MFD_CS47L92)) {
 655                        switch (madera->type) {
 656                        case CS42L92:
 657                        case CS47L92:
 658                        case CS47L93:
 659                                patch_fn = cs47l92_patch;
 660                                mfd_devs = cs47l92_devs;
 661                                n_devs = ARRAY_SIZE(cs47l92_devs);
 662                                break;
 663                        default:
 664                                break;
 665                        }
 666                }
 667                break;
 668        default:
 669                dev_err(madera->dev, "Unknown device ID: %x\n", hwid);
 670                ret = -EINVAL;
 671                goto err_reset;
 672        }
 673
 674        if (!n_devs) {
 675                dev_err(madera->dev, "Device ID 0x%x not a %s\n", hwid,
 676                        madera->type_name);
 677                ret = -ENODEV;
 678                goto err_reset;
 679        }
 680
 681        /*
 682         * It looks like a device we support. If we don't have a hard reset
 683         * we can now attempt a soft reset.
 684         */
 685        if (!madera->pdata.reset || madera->reset_errata) {
 686                ret = madera_soft_reset(madera);
 687                if (ret)
 688                        goto err_reset;
 689        }
 690
 691        ret = madera_wait_for_boot(madera);
 692        if (ret) {
 693                dev_err(madera->dev, "Failed to clear boot done: %d\n", ret);
 694                goto err_reset;
 695        }
 696
 697        ret = regmap_read(madera->regmap, MADERA_HARDWARE_REVISION,
 698                          &madera->rev);
 699        if (ret) {
 700                dev_err(dev, "Failed to read revision register: %d\n", ret);
 701                goto err_reset;
 702        }
 703        madera->rev &= MADERA_HW_REVISION_MASK;
 704
 705        dev_info(dev, "%s silicon revision %d\n", madera->type_name,
 706                 madera->rev);
 707
 708        /* Apply hardware patch */
 709        if (patch_fn) {
 710                ret = patch_fn(madera);
 711                if (ret) {
 712                        dev_err(madera->dev, "Failed to apply patch %d\n", ret);
 713                        goto err_reset;
 714                }
 715        }
 716
 717        /* Init 32k clock sourced from MCLK2 */
 718        ret = clk_prepare_enable(madera->mclk[MADERA_MCLK2].clk);
 719        if (ret) {
 720                dev_err(madera->dev, "Failed to enable 32k clock: %d\n", ret);
 721                goto err_reset;
 722        }
 723
 724        ret = regmap_update_bits(madera->regmap,
 725                        MADERA_CLOCK_32K_1,
 726                        MADERA_CLK_32K_ENA_MASK | MADERA_CLK_32K_SRC_MASK,
 727                        MADERA_CLK_32K_ENA | MADERA_32KZ_MCLK2);
 728        if (ret) {
 729                dev_err(madera->dev, "Failed to init 32k clock: %d\n", ret);
 730                goto err_clock;
 731        }
 732
 733        pm_runtime_set_active(madera->dev);
 734        pm_runtime_enable(madera->dev);
 735        pm_runtime_set_autosuspend_delay(madera->dev, 100);
 736        pm_runtime_use_autosuspend(madera->dev);
 737
 738        /* No devm_ because we need to control shutdown order of children */
 739        ret = mfd_add_devices(madera->dev, PLATFORM_DEVID_NONE,
 740                              mfd_devs, n_devs,
 741                              NULL, 0, NULL);
 742        if (ret) {
 743                dev_err(madera->dev, "Failed to add subdevices: %d\n", ret);
 744                goto err_pm_runtime;
 745        }
 746
 747        return 0;
 748
 749err_pm_runtime:
 750        pm_runtime_disable(madera->dev);
 751err_clock:
 752        clk_disable_unprepare(madera->mclk[MADERA_MCLK2].clk);
 753err_reset:
 754        madera_enable_hard_reset(madera);
 755        regulator_disable(madera->dcvdd);
 756err_enable:
 757        regulator_bulk_disable(madera->num_core_supplies,
 758                               madera->core_supplies);
 759err_dcvdd:
 760        regulator_put(madera->dcvdd);
 761err_devs:
 762        mfd_remove_devices(dev);
 763
 764        return ret;
 765}
 766EXPORT_SYMBOL_GPL(madera_dev_init);
 767
 768int madera_dev_exit(struct madera *madera)
 769{
 770        /* Prevent any IRQs being serviced while we clean up */
 771        disable_irq(madera->irq);
 772
 773        pm_runtime_get_sync(madera->dev);
 774
 775        mfd_remove_devices(madera->dev);
 776
 777        pm_runtime_disable(madera->dev);
 778
 779        regulator_disable(madera->dcvdd);
 780        regulator_put(madera->dcvdd);
 781
 782        mfd_remove_devices_late(madera->dev);
 783
 784        pm_runtime_set_suspended(madera->dev);
 785        pm_runtime_put_noidle(madera->dev);
 786
 787        clk_disable_unprepare(madera->mclk[MADERA_MCLK2].clk);
 788
 789        madera_enable_hard_reset(madera);
 790
 791        regulator_bulk_disable(madera->num_core_supplies,
 792                               madera->core_supplies);
 793        return 0;
 794}
 795EXPORT_SYMBOL_GPL(madera_dev_exit);
 796
 797MODULE_DESCRIPTION("Madera core MFD driver");
 798MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
 799MODULE_LICENSE("GPL v2");
 800