linux/drivers/mfd/max77620.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Maxim MAX77620 MFD Driver
   4 *
   5 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
   6 *
   7 * Author:
   8 *      Laxman Dewangan <ldewangan@nvidia.com>
   9 *      Chaitanya Bandi <bandik@nvidia.com>
  10 *      Mallikarjun Kasoju <mkasoju@nvidia.com>
  11 */
  12
  13/****************** Teminology used in driver ********************
  14 * Here are some terminology used from datasheet for quick reference:
  15 * Flexible Power Sequence (FPS):
  16 * The Flexible Power Sequencer (FPS) allows each regulator to power up under
  17 * hardware or software control. Additionally, each regulator can power on
  18 * independently or among a group of other regulators with an adjustable
  19 * power-up and power-down delays (sequencing). GPIO1, GPIO2, and GPIO3 can
  20 * be programmed to be part of a sequence allowing external regulators to be
  21 * sequenced along with internal regulators. 32KHz clock can be programmed to
  22 * be part of a sequence.
  23 * There is 3 FPS confguration registers and all resources are configured to
  24 * any of these FPS or no FPS.
  25 */
  26
  27#include <linux/i2c.h>
  28#include <linux/interrupt.h>
  29#include <linux/mfd/core.h>
  30#include <linux/mfd/max77620.h>
  31#include <linux/init.h>
  32#include <linux/of.h>
  33#include <linux/of_device.h>
  34#include <linux/regmap.h>
  35#include <linux/slab.h>
  36
  37static struct max77620_chip *max77620_scratch;
  38
  39static const struct resource gpio_resources[] = {
  40        DEFINE_RES_IRQ(MAX77620_IRQ_TOP_GPIO),
  41};
  42
  43static const struct resource power_resources[] = {
  44        DEFINE_RES_IRQ(MAX77620_IRQ_LBT_MBATLOW),
  45};
  46
  47static const struct resource rtc_resources[] = {
  48        DEFINE_RES_IRQ(MAX77620_IRQ_TOP_RTC),
  49};
  50
  51static const struct resource thermal_resources[] = {
  52        DEFINE_RES_IRQ(MAX77620_IRQ_LBT_TJALRM1),
  53        DEFINE_RES_IRQ(MAX77620_IRQ_LBT_TJALRM2),
  54};
  55
  56static const struct regmap_irq max77620_top_irqs[] = {
  57        REGMAP_IRQ_REG(MAX77620_IRQ_TOP_GLBL, 0, MAX77620_IRQ_TOP_GLBL_MASK),
  58        REGMAP_IRQ_REG(MAX77620_IRQ_TOP_SD, 0, MAX77620_IRQ_TOP_SD_MASK),
  59        REGMAP_IRQ_REG(MAX77620_IRQ_TOP_LDO, 0, MAX77620_IRQ_TOP_LDO_MASK),
  60        REGMAP_IRQ_REG(MAX77620_IRQ_TOP_GPIO, 0, MAX77620_IRQ_TOP_GPIO_MASK),
  61        REGMAP_IRQ_REG(MAX77620_IRQ_TOP_RTC, 0, MAX77620_IRQ_TOP_RTC_MASK),
  62        REGMAP_IRQ_REG(MAX77620_IRQ_TOP_32K, 0, MAX77620_IRQ_TOP_32K_MASK),
  63        REGMAP_IRQ_REG(MAX77620_IRQ_TOP_ONOFF, 0, MAX77620_IRQ_TOP_ONOFF_MASK),
  64        REGMAP_IRQ_REG(MAX77620_IRQ_LBT_MBATLOW, 1, MAX77620_IRQ_LBM_MASK),
  65        REGMAP_IRQ_REG(MAX77620_IRQ_LBT_TJALRM1, 1, MAX77620_IRQ_TJALRM1_MASK),
  66        REGMAP_IRQ_REG(MAX77620_IRQ_LBT_TJALRM2, 1, MAX77620_IRQ_TJALRM2_MASK),
  67};
  68
  69static const struct mfd_cell max77620_children[] = {
  70        { .name = "max77620-pinctrl", },
  71        { .name = "max77620-clock", },
  72        { .name = "max77620-pmic", },
  73        { .name = "max77620-watchdog", },
  74        {
  75                .name = "max77620-gpio",
  76                .resources = gpio_resources,
  77                .num_resources = ARRAY_SIZE(gpio_resources),
  78        }, {
  79                .name = "max77620-rtc",
  80                .resources = rtc_resources,
  81                .num_resources = ARRAY_SIZE(rtc_resources),
  82        }, {
  83                .name = "max77620-power",
  84                .resources = power_resources,
  85                .num_resources = ARRAY_SIZE(power_resources),
  86        }, {
  87                .name = "max77620-thermal",
  88                .resources = thermal_resources,
  89                .num_resources = ARRAY_SIZE(thermal_resources),
  90        },
  91};
  92
  93static const struct mfd_cell max20024_children[] = {
  94        { .name = "max20024-pinctrl", },
  95        { .name = "max77620-clock", },
  96        { .name = "max20024-pmic", },
  97        { .name = "max77620-watchdog", },
  98        {
  99                .name = "max77620-gpio",
 100                .resources = gpio_resources,
 101                .num_resources = ARRAY_SIZE(gpio_resources),
 102        }, {
 103                .name = "max77620-rtc",
 104                .resources = rtc_resources,
 105                .num_resources = ARRAY_SIZE(rtc_resources),
 106        }, {
 107                .name = "max20024-power",
 108                .resources = power_resources,
 109                .num_resources = ARRAY_SIZE(power_resources),
 110        },
 111};
 112
 113static const struct mfd_cell max77663_children[] = {
 114        { .name = "max77620-pinctrl", },
 115        { .name = "max77620-clock", },
 116        { .name = "max77663-pmic", },
 117        { .name = "max77620-watchdog", },
 118        {
 119                .name = "max77620-gpio",
 120                .resources = gpio_resources,
 121                .num_resources = ARRAY_SIZE(gpio_resources),
 122        }, {
 123                .name = "max77620-rtc",
 124                .resources = rtc_resources,
 125                .num_resources = ARRAY_SIZE(rtc_resources),
 126        }, {
 127                .name = "max77663-power",
 128                .resources = power_resources,
 129                .num_resources = ARRAY_SIZE(power_resources),
 130        },
 131};
 132
 133static const struct regmap_range max77620_readable_ranges[] = {
 134        regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4),
 135};
 136
 137static const struct regmap_access_table max77620_readable_table = {
 138        .yes_ranges = max77620_readable_ranges,
 139        .n_yes_ranges = ARRAY_SIZE(max77620_readable_ranges),
 140};
 141
 142static const struct regmap_range max20024_readable_ranges[] = {
 143        regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4),
 144        regmap_reg_range(MAX20024_REG_MAX_ADD, MAX20024_REG_MAX_ADD),
 145};
 146
 147static const struct regmap_access_table max20024_readable_table = {
 148        .yes_ranges = max20024_readable_ranges,
 149        .n_yes_ranges = ARRAY_SIZE(max20024_readable_ranges),
 150};
 151
 152static const struct regmap_range max77620_writable_ranges[] = {
 153        regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4),
 154};
 155
 156static const struct regmap_access_table max77620_writable_table = {
 157        .yes_ranges = max77620_writable_ranges,
 158        .n_yes_ranges = ARRAY_SIZE(max77620_writable_ranges),
 159};
 160
 161static const struct regmap_range max77620_cacheable_ranges[] = {
 162        regmap_reg_range(MAX77620_REG_SD0_CFG, MAX77620_REG_LDO_CFG3),
 163        regmap_reg_range(MAX77620_REG_FPS_CFG0, MAX77620_REG_FPS_SD3),
 164};
 165
 166static const struct regmap_access_table max77620_volatile_table = {
 167        .no_ranges = max77620_cacheable_ranges,
 168        .n_no_ranges = ARRAY_SIZE(max77620_cacheable_ranges),
 169};
 170
 171static const struct regmap_config max77620_regmap_config = {
 172        .name = "power-slave",
 173        .reg_bits = 8,
 174        .val_bits = 8,
 175        .max_register = MAX77620_REG_DVSSD4 + 1,
 176        .cache_type = REGCACHE_RBTREE,
 177        .rd_table = &max77620_readable_table,
 178        .wr_table = &max77620_writable_table,
 179        .volatile_table = &max77620_volatile_table,
 180        .use_single_write = true,
 181};
 182
 183static const struct regmap_config max20024_regmap_config = {
 184        .name = "power-slave",
 185        .reg_bits = 8,
 186        .val_bits = 8,
 187        .max_register = MAX20024_REG_MAX_ADD + 1,
 188        .cache_type = REGCACHE_RBTREE,
 189        .rd_table = &max20024_readable_table,
 190        .wr_table = &max77620_writable_table,
 191        .volatile_table = &max77620_volatile_table,
 192};
 193
 194static const struct regmap_range max77663_readable_ranges[] = {
 195        regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_CID5),
 196};
 197
 198static const struct regmap_access_table max77663_readable_table = {
 199        .yes_ranges = max77663_readable_ranges,
 200        .n_yes_ranges = ARRAY_SIZE(max77663_readable_ranges),
 201};
 202
 203static const struct regmap_range max77663_writable_ranges[] = {
 204        regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_CID5),
 205};
 206
 207static const struct regmap_access_table max77663_writable_table = {
 208        .yes_ranges = max77663_writable_ranges,
 209        .n_yes_ranges = ARRAY_SIZE(max77663_writable_ranges),
 210};
 211
 212static const struct regmap_config max77663_regmap_config = {
 213        .name = "power-slave",
 214        .reg_bits = 8,
 215        .val_bits = 8,
 216        .max_register = MAX77620_REG_CID5 + 1,
 217        .cache_type = REGCACHE_RBTREE,
 218        .rd_table = &max77663_readable_table,
 219        .wr_table = &max77663_writable_table,
 220        .volatile_table = &max77620_volatile_table,
 221};
 222
 223/*
 224 * MAX77620 and MAX20024 has the following steps of the interrupt handling
 225 * for TOP interrupts:
 226 * 1. When interrupt occurs from PMIC, mask the PMIC interrupt by setting GLBLM.
 227 * 2. Read IRQTOP and service the interrupt.
 228 * 3. Once all interrupts has been checked and serviced, the interrupt service
 229 *    routine un-masks the hardware interrupt line by clearing GLBLM.
 230 */
 231static int max77620_irq_global_mask(void *irq_drv_data)
 232{
 233        struct max77620_chip *chip = irq_drv_data;
 234        int ret;
 235
 236        ret = regmap_update_bits(chip->rmap, MAX77620_REG_INTENLBT,
 237                                 MAX77620_GLBLM_MASK, MAX77620_GLBLM_MASK);
 238        if (ret < 0)
 239                dev_err(chip->dev, "Failed to set GLBLM: %d\n", ret);
 240
 241        return ret;
 242}
 243
 244static int max77620_irq_global_unmask(void *irq_drv_data)
 245{
 246        struct max77620_chip *chip = irq_drv_data;
 247        int ret;
 248
 249        ret = regmap_update_bits(chip->rmap, MAX77620_REG_INTENLBT,
 250                                 MAX77620_GLBLM_MASK, 0);
 251        if (ret < 0)
 252                dev_err(chip->dev, "Failed to reset GLBLM: %d\n", ret);
 253
 254        return ret;
 255}
 256
 257static struct regmap_irq_chip max77620_top_irq_chip = {
 258        .name = "max77620-top",
 259        .irqs = max77620_top_irqs,
 260        .num_irqs = ARRAY_SIZE(max77620_top_irqs),
 261        .num_regs = 2,
 262        .status_base = MAX77620_REG_IRQTOP,
 263        .mask_base = MAX77620_REG_IRQTOPM,
 264        .handle_pre_irq = max77620_irq_global_mask,
 265        .handle_post_irq = max77620_irq_global_unmask,
 266};
 267
 268/* max77620_get_fps_period_reg_value:  Get FPS bit field value from
 269 *                                     requested periods.
 270 * MAX77620 supports the FPS period of 40, 80, 160, 320, 540, 1280, 2560
 271 * and 5120 microseconds. MAX20024 supports the FPS period of 20, 40, 80,
 272 * 160, 320, 540, 1280 and 2560 microseconds.
 273 * The FPS register has 3 bits field to set the FPS period as
 274 * bits         max77620                max20024
 275 * 000          40                      20
 276 * 001          80                      40
 277 * :::
 278*/
 279static int max77620_get_fps_period_reg_value(struct max77620_chip *chip,
 280                                             int tperiod)
 281{
 282        int fps_min_period;
 283        int i;
 284
 285        switch (chip->chip_id) {
 286        case MAX20024:
 287                fps_min_period = MAX20024_FPS_PERIOD_MIN_US;
 288                break;
 289        case MAX77620:
 290                fps_min_period = MAX77620_FPS_PERIOD_MIN_US;
 291                break;
 292        case MAX77663:
 293                fps_min_period = MAX20024_FPS_PERIOD_MIN_US;
 294                break;
 295        default:
 296                return -EINVAL;
 297        }
 298
 299        for (i = 0; i < 7; i++) {
 300                if (fps_min_period >= tperiod)
 301                        return i;
 302                fps_min_period *= 2;
 303        }
 304
 305        return i;
 306}
 307
 308/* max77620_config_fps: Configure FPS configuration registers
 309 *                      based on platform specific information.
 310 */
 311static int max77620_config_fps(struct max77620_chip *chip,
 312                               struct device_node *fps_np)
 313{
 314        struct device *dev = chip->dev;
 315        unsigned int mask = 0, config = 0;
 316        u32 fps_max_period;
 317        u32 param_val;
 318        int tperiod, fps_id;
 319        int ret;
 320        char fps_name[10];
 321
 322        switch (chip->chip_id) {
 323        case MAX20024:
 324                fps_max_period = MAX20024_FPS_PERIOD_MAX_US;
 325                break;
 326        case MAX77620:
 327                fps_max_period = MAX77620_FPS_PERIOD_MAX_US;
 328                break;
 329        case MAX77663:
 330                fps_max_period = MAX20024_FPS_PERIOD_MAX_US;
 331                break;
 332        default:
 333                return -EINVAL;
 334        }
 335
 336        for (fps_id = 0; fps_id < MAX77620_FPS_COUNT; fps_id++) {
 337                sprintf(fps_name, "fps%d", fps_id);
 338                if (of_node_name_eq(fps_np, fps_name))
 339                        break;
 340        }
 341
 342        if (fps_id == MAX77620_FPS_COUNT) {
 343                dev_err(dev, "FPS node name %pOFn is not valid\n", fps_np);
 344                return -EINVAL;
 345        }
 346
 347        ret = of_property_read_u32(fps_np, "maxim,shutdown-fps-time-period-us",
 348                                   &param_val);
 349        if (!ret) {
 350                mask |= MAX77620_FPS_TIME_PERIOD_MASK;
 351                chip->shutdown_fps_period[fps_id] = min(param_val,
 352                                                        fps_max_period);
 353                tperiod = max77620_get_fps_period_reg_value(chip,
 354                                chip->shutdown_fps_period[fps_id]);
 355                config |= tperiod << MAX77620_FPS_TIME_PERIOD_SHIFT;
 356        }
 357
 358        ret = of_property_read_u32(fps_np, "maxim,suspend-fps-time-period-us",
 359                                   &param_val);
 360        if (!ret)
 361                chip->suspend_fps_period[fps_id] = min(param_val,
 362                                                       fps_max_period);
 363
 364        ret = of_property_read_u32(fps_np, "maxim,fps-event-source",
 365                                   &param_val);
 366        if (!ret) {
 367                if (param_val > 2) {
 368                        dev_err(dev, "FPS%d event-source invalid\n", fps_id);
 369                        return -EINVAL;
 370                }
 371                mask |= MAX77620_FPS_EN_SRC_MASK;
 372                config |= param_val << MAX77620_FPS_EN_SRC_SHIFT;
 373                if (param_val == 2) {
 374                        mask |= MAX77620_FPS_ENFPS_SW_MASK;
 375                        config |= MAX77620_FPS_ENFPS_SW;
 376                }
 377        }
 378
 379        if (!chip->sleep_enable && !chip->enable_global_lpm) {
 380                ret = of_property_read_u32(fps_np,
 381                                "maxim,device-state-on-disabled-event",
 382                                &param_val);
 383                if (!ret) {
 384                        if (param_val == 0)
 385                                chip->sleep_enable = true;
 386                        else if (param_val == 1)
 387                                chip->enable_global_lpm = true;
 388                }
 389        }
 390
 391        ret = regmap_update_bits(chip->rmap, MAX77620_REG_FPS_CFG0 + fps_id,
 392                                 mask, config);
 393        if (ret < 0) {
 394                dev_err(dev, "Failed to update FPS CFG: %d\n", ret);
 395                return ret;
 396        }
 397
 398        return 0;
 399}
 400
 401static int max77620_initialise_fps(struct max77620_chip *chip)
 402{
 403        struct device *dev = chip->dev;
 404        struct device_node *fps_np, *fps_child;
 405        u8 config;
 406        int fps_id;
 407        int ret;
 408
 409        for (fps_id = 0; fps_id < MAX77620_FPS_COUNT; fps_id++) {
 410                chip->shutdown_fps_period[fps_id] = -1;
 411                chip->suspend_fps_period[fps_id] = -1;
 412        }
 413
 414        fps_np = of_get_child_by_name(dev->of_node, "fps");
 415        if (!fps_np)
 416                goto skip_fps;
 417
 418        for_each_child_of_node(fps_np, fps_child) {
 419                ret = max77620_config_fps(chip, fps_child);
 420                if (ret < 0) {
 421                        of_node_put(fps_child);
 422                        return ret;
 423                }
 424        }
 425
 426        config = chip->enable_global_lpm ? MAX77620_ONOFFCNFG2_SLP_LPM_MSK : 0;
 427        ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
 428                                 MAX77620_ONOFFCNFG2_SLP_LPM_MSK, config);
 429        if (ret < 0) {
 430                dev_err(dev, "Failed to update SLP_LPM: %d\n", ret);
 431                return ret;
 432        }
 433
 434skip_fps:
 435        if (chip->chip_id == MAX77663)
 436                return 0;
 437
 438        /* Enable wake on EN0 pin */
 439        ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
 440                                 MAX77620_ONOFFCNFG2_WK_EN0,
 441                                 MAX77620_ONOFFCNFG2_WK_EN0);
 442        if (ret < 0) {
 443                dev_err(dev, "Failed to update WK_EN0: %d\n", ret);
 444                return ret;
 445        }
 446
 447        /* For MAX20024, SLPEN will be POR reset if CLRSE is b11 */
 448        if ((chip->chip_id == MAX20024) && chip->sleep_enable) {
 449                config = MAX77620_ONOFFCNFG1_SLPEN | MAX20024_ONOFFCNFG1_CLRSE;
 450                ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG1,
 451                                         config, config);
 452                if (ret < 0) {
 453                        dev_err(dev, "Failed to update SLPEN: %d\n", ret);
 454                        return ret;
 455                }
 456        }
 457
 458        return 0;
 459}
 460
 461static int max77620_read_es_version(struct max77620_chip *chip)
 462{
 463        unsigned int val;
 464        u8 cid_val[6];
 465        int i;
 466        int ret;
 467
 468        for (i = MAX77620_REG_CID0; i <= MAX77620_REG_CID5; i++) {
 469                ret = regmap_read(chip->rmap, i, &val);
 470                if (ret < 0) {
 471                        dev_err(chip->dev, "Failed to read CID: %d\n", ret);
 472                        return ret;
 473                }
 474                dev_dbg(chip->dev, "CID%d: 0x%02x\n",
 475                        i - MAX77620_REG_CID0, val);
 476                cid_val[i - MAX77620_REG_CID0] = val;
 477        }
 478
 479        /* CID4 is OTP Version  and CID5 is ES version */
 480        dev_info(chip->dev, "PMIC Version OTP:0x%02X and ES:0x%X\n",
 481                 cid_val[4], MAX77620_CID5_DIDM(cid_val[5]));
 482
 483        return ret;
 484}
 485
 486static void max77620_pm_power_off(void)
 487{
 488        struct max77620_chip *chip = max77620_scratch;
 489
 490        regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG1,
 491                           MAX77620_ONOFFCNFG1_SFT_RST,
 492                           MAX77620_ONOFFCNFG1_SFT_RST);
 493}
 494
 495static int max77620_probe(struct i2c_client *client,
 496                          const struct i2c_device_id *id)
 497{
 498        const struct regmap_config *rmap_config;
 499        struct max77620_chip *chip;
 500        const struct mfd_cell *mfd_cells;
 501        int n_mfd_cells;
 502        bool pm_off;
 503        int ret;
 504
 505        chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
 506        if (!chip)
 507                return -ENOMEM;
 508
 509        i2c_set_clientdata(client, chip);
 510        chip->dev = &client->dev;
 511        chip->chip_irq = client->irq;
 512        chip->chip_id = (enum max77620_chip_id)id->driver_data;
 513
 514        switch (chip->chip_id) {
 515        case MAX77620:
 516                mfd_cells = max77620_children;
 517                n_mfd_cells = ARRAY_SIZE(max77620_children);
 518                rmap_config = &max77620_regmap_config;
 519                break;
 520        case MAX20024:
 521                mfd_cells = max20024_children;
 522                n_mfd_cells = ARRAY_SIZE(max20024_children);
 523                rmap_config = &max20024_regmap_config;
 524                break;
 525        case MAX77663:
 526                mfd_cells = max77663_children;
 527                n_mfd_cells = ARRAY_SIZE(max77663_children);
 528                rmap_config = &max77663_regmap_config;
 529                break;
 530        default:
 531                dev_err(chip->dev, "ChipID is invalid %d\n", chip->chip_id);
 532                return -EINVAL;
 533        }
 534
 535        chip->rmap = devm_regmap_init_i2c(client, rmap_config);
 536        if (IS_ERR(chip->rmap)) {
 537                ret = PTR_ERR(chip->rmap);
 538                dev_err(chip->dev, "Failed to initialise regmap: %d\n", ret);
 539                return ret;
 540        }
 541
 542        ret = max77620_read_es_version(chip);
 543        if (ret < 0)
 544                return ret;
 545
 546        max77620_top_irq_chip.irq_drv_data = chip;
 547        ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq,
 548                                       IRQF_ONESHOT | IRQF_SHARED, 0,
 549                                       &max77620_top_irq_chip,
 550                                       &chip->top_irq_data);
 551        if (ret < 0) {
 552                dev_err(chip->dev, "Failed to add regmap irq: %d\n", ret);
 553                return ret;
 554        }
 555
 556        ret = max77620_initialise_fps(chip);
 557        if (ret < 0)
 558                return ret;
 559
 560        ret =  devm_mfd_add_devices(chip->dev, PLATFORM_DEVID_NONE,
 561                                    mfd_cells, n_mfd_cells, NULL, 0,
 562                                    regmap_irq_get_domain(chip->top_irq_data));
 563        if (ret < 0) {
 564                dev_err(chip->dev, "Failed to add MFD children: %d\n", ret);
 565                return ret;
 566        }
 567
 568        pm_off = of_device_is_system_power_controller(client->dev.of_node);
 569        if (pm_off && !pm_power_off) {
 570                max77620_scratch = chip;
 571                pm_power_off = max77620_pm_power_off;
 572        }
 573
 574        return 0;
 575}
 576
 577#ifdef CONFIG_PM_SLEEP
 578static int max77620_set_fps_period(struct max77620_chip *chip,
 579                                   int fps_id, int time_period)
 580{
 581        int period = max77620_get_fps_period_reg_value(chip, time_period);
 582        int ret;
 583
 584        ret = regmap_update_bits(chip->rmap, MAX77620_REG_FPS_CFG0 + fps_id,
 585                                 MAX77620_FPS_TIME_PERIOD_MASK,
 586                                 period << MAX77620_FPS_TIME_PERIOD_SHIFT);
 587        if (ret < 0) {
 588                dev_err(chip->dev, "Failed to update FPS period: %d\n", ret);
 589                return ret;
 590        }
 591
 592        return 0;
 593}
 594
 595static int max77620_i2c_suspend(struct device *dev)
 596{
 597        struct max77620_chip *chip = dev_get_drvdata(dev);
 598        struct i2c_client *client = to_i2c_client(dev);
 599        unsigned int config;
 600        int fps;
 601        int ret;
 602
 603        for (fps = 0; fps < MAX77620_FPS_COUNT; fps++) {
 604                if (chip->suspend_fps_period[fps] < 0)
 605                        continue;
 606
 607                ret = max77620_set_fps_period(chip, fps,
 608                                              chip->suspend_fps_period[fps]);
 609                if (ret < 0)
 610                        return ret;
 611        }
 612
 613        /*
 614         * For MAX20024: No need to configure SLPEN on suspend as
 615         * it will be configured on Init.
 616         */
 617        if (chip->chip_id == MAX20024)
 618                goto out;
 619
 620        config = (chip->sleep_enable) ? MAX77620_ONOFFCNFG1_SLPEN : 0;
 621        ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG1,
 622                                 MAX77620_ONOFFCNFG1_SLPEN,
 623                                 config);
 624        if (ret < 0) {
 625                dev_err(dev, "Failed to configure sleep in suspend: %d\n", ret);
 626                return ret;
 627        }
 628
 629        if (chip->chip_id == MAX77663)
 630                goto out;
 631
 632        /* Disable WK_EN0 */
 633        ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
 634                                 MAX77620_ONOFFCNFG2_WK_EN0, 0);
 635        if (ret < 0) {
 636                dev_err(dev, "Failed to configure WK_EN in suspend: %d\n", ret);
 637                return ret;
 638        }
 639
 640out:
 641        disable_irq(client->irq);
 642
 643        return 0;
 644}
 645
 646static int max77620_i2c_resume(struct device *dev)
 647{
 648        struct max77620_chip *chip = dev_get_drvdata(dev);
 649        struct i2c_client *client = to_i2c_client(dev);
 650        int ret;
 651        int fps;
 652
 653        for (fps = 0; fps < MAX77620_FPS_COUNT; fps++) {
 654                if (chip->shutdown_fps_period[fps] < 0)
 655                        continue;
 656
 657                ret = max77620_set_fps_period(chip, fps,
 658                                              chip->shutdown_fps_period[fps]);
 659                if (ret < 0)
 660                        return ret;
 661        }
 662
 663        /*
 664         * For MAX20024: No need to configure WKEN0 on resume as
 665         * it is configured on Init.
 666         */
 667        if (chip->chip_id == MAX20024 || chip->chip_id == MAX77663)
 668                goto out;
 669
 670        /* Enable WK_EN0 */
 671        ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
 672                                 MAX77620_ONOFFCNFG2_WK_EN0,
 673                                 MAX77620_ONOFFCNFG2_WK_EN0);
 674        if (ret < 0) {
 675                dev_err(dev, "Failed to configure WK_EN0 n resume: %d\n", ret);
 676                return ret;
 677        }
 678
 679out:
 680        enable_irq(client->irq);
 681
 682        return 0;
 683}
 684#endif
 685
 686static const struct i2c_device_id max77620_id[] = {
 687        {"max77620", MAX77620},
 688        {"max20024", MAX20024},
 689        {"max77663", MAX77663},
 690        {},
 691};
 692
 693static const struct dev_pm_ops max77620_pm_ops = {
 694        SET_SYSTEM_SLEEP_PM_OPS(max77620_i2c_suspend, max77620_i2c_resume)
 695};
 696
 697static struct i2c_driver max77620_driver = {
 698        .driver = {
 699                .name = "max77620",
 700                .pm = &max77620_pm_ops,
 701        },
 702        .probe = max77620_probe,
 703        .id_table = max77620_id,
 704};
 705builtin_i2c_driver(max77620_driver);
 706