Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Maxim MAX77620 MFD Driver
0004  *
0005  * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
0006  *
0007  * Author:
0008  *  Laxman Dewangan <ldewangan@nvidia.com>
0009  *  Chaitanya Bandi <bandik@nvidia.com>
0010  *  Mallikarjun Kasoju <mkasoju@nvidia.com>
0011  */
0012 
0013 /****************** Teminology used in driver ********************
0014  * Here are some terminology used from datasheet for quick reference:
0015  * Flexible Power Sequence (FPS):
0016  * The Flexible Power Sequencer (FPS) allows each regulator to power up under
0017  * hardware or software control. Additionally, each regulator can power on
0018  * independently or among a group of other regulators with an adjustable
0019  * power-up and power-down delays (sequencing). GPIO1, GPIO2, and GPIO3 can
0020  * be programmed to be part of a sequence allowing external regulators to be
0021  * sequenced along with internal regulators. 32KHz clock can be programmed to
0022  * be part of a sequence.
0023  * There is 3 FPS confguration registers and all resources are configured to
0024  * any of these FPS or no FPS.
0025  */
0026 
0027 #include <linux/i2c.h>
0028 #include <linux/interrupt.h>
0029 #include <linux/mfd/core.h>
0030 #include <linux/mfd/max77620.h>
0031 #include <linux/init.h>
0032 #include <linux/of.h>
0033 #include <linux/of_device.h>
0034 #include <linux/regmap.h>
0035 #include <linux/slab.h>
0036 
0037 static struct max77620_chip *max77620_scratch;
0038 
0039 static const struct resource gpio_resources[] = {
0040     DEFINE_RES_IRQ(MAX77620_IRQ_TOP_GPIO),
0041 };
0042 
0043 static const struct resource power_resources[] = {
0044     DEFINE_RES_IRQ(MAX77620_IRQ_LBT_MBATLOW),
0045 };
0046 
0047 static const struct resource rtc_resources[] = {
0048     DEFINE_RES_IRQ(MAX77620_IRQ_TOP_RTC),
0049 };
0050 
0051 static const struct resource thermal_resources[] = {
0052     DEFINE_RES_IRQ(MAX77620_IRQ_LBT_TJALRM1),
0053     DEFINE_RES_IRQ(MAX77620_IRQ_LBT_TJALRM2),
0054 };
0055 
0056 static const struct regmap_irq max77620_top_irqs[] = {
0057     REGMAP_IRQ_REG(MAX77620_IRQ_TOP_GLBL, 0, MAX77620_IRQ_TOP_GLBL_MASK),
0058     REGMAP_IRQ_REG(MAX77620_IRQ_TOP_SD, 0, MAX77620_IRQ_TOP_SD_MASK),
0059     REGMAP_IRQ_REG(MAX77620_IRQ_TOP_LDO, 0, MAX77620_IRQ_TOP_LDO_MASK),
0060     REGMAP_IRQ_REG(MAX77620_IRQ_TOP_GPIO, 0, MAX77620_IRQ_TOP_GPIO_MASK),
0061     REGMAP_IRQ_REG(MAX77620_IRQ_TOP_RTC, 0, MAX77620_IRQ_TOP_RTC_MASK),
0062     REGMAP_IRQ_REG(MAX77620_IRQ_TOP_32K, 0, MAX77620_IRQ_TOP_32K_MASK),
0063     REGMAP_IRQ_REG(MAX77620_IRQ_TOP_ONOFF, 0, MAX77620_IRQ_TOP_ONOFF_MASK),
0064     REGMAP_IRQ_REG(MAX77620_IRQ_LBT_MBATLOW, 1, MAX77620_IRQ_LBM_MASK),
0065     REGMAP_IRQ_REG(MAX77620_IRQ_LBT_TJALRM1, 1, MAX77620_IRQ_TJALRM1_MASK),
0066     REGMAP_IRQ_REG(MAX77620_IRQ_LBT_TJALRM2, 1, MAX77620_IRQ_TJALRM2_MASK),
0067 };
0068 
0069 static const struct mfd_cell max77620_children[] = {
0070     { .name = "max77620-pinctrl", },
0071     { .name = "max77620-clock", },
0072     { .name = "max77620-pmic", },
0073     { .name = "max77620-watchdog", },
0074     {
0075         .name = "max77620-gpio",
0076         .resources = gpio_resources,
0077         .num_resources = ARRAY_SIZE(gpio_resources),
0078     }, {
0079         .name = "max77620-rtc",
0080         .resources = rtc_resources,
0081         .num_resources = ARRAY_SIZE(rtc_resources),
0082     }, {
0083         .name = "max77620-power",
0084         .resources = power_resources,
0085         .num_resources = ARRAY_SIZE(power_resources),
0086     }, {
0087         .name = "max77620-thermal",
0088         .resources = thermal_resources,
0089         .num_resources = ARRAY_SIZE(thermal_resources),
0090     },
0091 };
0092 
0093 static const struct mfd_cell max20024_children[] = {
0094     { .name = "max20024-pinctrl", },
0095     { .name = "max77620-clock", },
0096     { .name = "max20024-pmic", },
0097     { .name = "max77620-watchdog", },
0098     {
0099         .name = "max77620-gpio",
0100         .resources = gpio_resources,
0101         .num_resources = ARRAY_SIZE(gpio_resources),
0102     }, {
0103         .name = "max77620-rtc",
0104         .resources = rtc_resources,
0105         .num_resources = ARRAY_SIZE(rtc_resources),
0106     }, {
0107         .name = "max20024-power",
0108         .resources = power_resources,
0109         .num_resources = ARRAY_SIZE(power_resources),
0110     },
0111 };
0112 
0113 static const struct mfd_cell max77663_children[] = {
0114     { .name = "max77620-pinctrl", },
0115     { .name = "max77620-clock", },
0116     { .name = "max77663-pmic", },
0117     { .name = "max77620-watchdog", },
0118     {
0119         .name = "max77620-gpio",
0120         .resources = gpio_resources,
0121         .num_resources = ARRAY_SIZE(gpio_resources),
0122     }, {
0123         .name = "max77620-rtc",
0124         .resources = rtc_resources,
0125         .num_resources = ARRAY_SIZE(rtc_resources),
0126     }, {
0127         .name = "max77663-power",
0128         .resources = power_resources,
0129         .num_resources = ARRAY_SIZE(power_resources),
0130     },
0131 };
0132 
0133 static const struct regmap_range max77620_readable_ranges[] = {
0134     regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4),
0135 };
0136 
0137 static const struct regmap_access_table max77620_readable_table = {
0138     .yes_ranges = max77620_readable_ranges,
0139     .n_yes_ranges = ARRAY_SIZE(max77620_readable_ranges),
0140 };
0141 
0142 static const struct regmap_range max20024_readable_ranges[] = {
0143     regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4),
0144     regmap_reg_range(MAX20024_REG_MAX_ADD, MAX20024_REG_MAX_ADD),
0145 };
0146 
0147 static const struct regmap_access_table max20024_readable_table = {
0148     .yes_ranges = max20024_readable_ranges,
0149     .n_yes_ranges = ARRAY_SIZE(max20024_readable_ranges),
0150 };
0151 
0152 static const struct regmap_range max77620_writable_ranges[] = {
0153     regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4),
0154 };
0155 
0156 static const struct regmap_access_table max77620_writable_table = {
0157     .yes_ranges = max77620_writable_ranges,
0158     .n_yes_ranges = ARRAY_SIZE(max77620_writable_ranges),
0159 };
0160 
0161 static const struct regmap_range max77620_cacheable_ranges[] = {
0162     regmap_reg_range(MAX77620_REG_SD0_CFG, MAX77620_REG_LDO_CFG3),
0163     regmap_reg_range(MAX77620_REG_FPS_CFG0, MAX77620_REG_FPS_SD3),
0164 };
0165 
0166 static const struct regmap_access_table max77620_volatile_table = {
0167     .no_ranges = max77620_cacheable_ranges,
0168     .n_no_ranges = ARRAY_SIZE(max77620_cacheable_ranges),
0169 };
0170 
0171 static const struct regmap_config max77620_regmap_config = {
0172     .name = "power-slave",
0173     .reg_bits = 8,
0174     .val_bits = 8,
0175     .max_register = MAX77620_REG_DVSSD4 + 1,
0176     .cache_type = REGCACHE_RBTREE,
0177     .rd_table = &max77620_readable_table,
0178     .wr_table = &max77620_writable_table,
0179     .volatile_table = &max77620_volatile_table,
0180     .use_single_write = true,
0181 };
0182 
0183 static const struct regmap_config max20024_regmap_config = {
0184     .name = "power-slave",
0185     .reg_bits = 8,
0186     .val_bits = 8,
0187     .max_register = MAX20024_REG_MAX_ADD + 1,
0188     .cache_type = REGCACHE_RBTREE,
0189     .rd_table = &max20024_readable_table,
0190     .wr_table = &max77620_writable_table,
0191     .volatile_table = &max77620_volatile_table,
0192 };
0193 
0194 static const struct regmap_range max77663_readable_ranges[] = {
0195     regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_CID5),
0196 };
0197 
0198 static const struct regmap_access_table max77663_readable_table = {
0199     .yes_ranges = max77663_readable_ranges,
0200     .n_yes_ranges = ARRAY_SIZE(max77663_readable_ranges),
0201 };
0202 
0203 static const struct regmap_range max77663_writable_ranges[] = {
0204     regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_CID5),
0205 };
0206 
0207 static const struct regmap_access_table max77663_writable_table = {
0208     .yes_ranges = max77663_writable_ranges,
0209     .n_yes_ranges = ARRAY_SIZE(max77663_writable_ranges),
0210 };
0211 
0212 static const struct regmap_config max77663_regmap_config = {
0213     .name = "power-slave",
0214     .reg_bits = 8,
0215     .val_bits = 8,
0216     .max_register = MAX77620_REG_CID5 + 1,
0217     .cache_type = REGCACHE_RBTREE,
0218     .rd_table = &max77663_readable_table,
0219     .wr_table = &max77663_writable_table,
0220     .volatile_table = &max77620_volatile_table,
0221 };
0222 
0223 /*
0224  * MAX77620 and MAX20024 has the following steps of the interrupt handling
0225  * for TOP interrupts:
0226  * 1. When interrupt occurs from PMIC, mask the PMIC interrupt by setting GLBLM.
0227  * 2. Read IRQTOP and service the interrupt.
0228  * 3. Once all interrupts has been checked and serviced, the interrupt service
0229  *    routine un-masks the hardware interrupt line by clearing GLBLM.
0230  */
0231 static int max77620_irq_global_mask(void *irq_drv_data)
0232 {
0233     struct max77620_chip *chip = irq_drv_data;
0234     int ret;
0235 
0236     ret = regmap_update_bits(chip->rmap, MAX77620_REG_INTENLBT,
0237                  MAX77620_GLBLM_MASK, MAX77620_GLBLM_MASK);
0238     if (ret < 0)
0239         dev_err(chip->dev, "Failed to set GLBLM: %d\n", ret);
0240 
0241     return ret;
0242 }
0243 
0244 static int max77620_irq_global_unmask(void *irq_drv_data)
0245 {
0246     struct max77620_chip *chip = irq_drv_data;
0247     int ret;
0248 
0249     ret = regmap_update_bits(chip->rmap, MAX77620_REG_INTENLBT,
0250                  MAX77620_GLBLM_MASK, 0);
0251     if (ret < 0)
0252         dev_err(chip->dev, "Failed to reset GLBLM: %d\n", ret);
0253 
0254     return ret;
0255 }
0256 
0257 static struct regmap_irq_chip max77620_top_irq_chip = {
0258     .name = "max77620-top",
0259     .irqs = max77620_top_irqs,
0260     .num_irqs = ARRAY_SIZE(max77620_top_irqs),
0261     .num_regs = 2,
0262     .status_base = MAX77620_REG_IRQTOP,
0263     .mask_base = MAX77620_REG_IRQTOPM,
0264     .handle_pre_irq = max77620_irq_global_mask,
0265     .handle_post_irq = max77620_irq_global_unmask,
0266 };
0267 
0268 /* max77620_get_fps_period_reg_value:  Get FPS bit field value from
0269  *                     requested periods.
0270  * MAX77620 supports the FPS period of 40, 80, 160, 320, 540, 1280, 2560
0271  * and 5120 microseconds. MAX20024 supports the FPS period of 20, 40, 80,
0272  * 160, 320, 540, 1280 and 2560 microseconds.
0273  * The FPS register has 3 bits field to set the FPS period as
0274  * bits     max77620        max20024
0275  * 000      40          20
0276  * 001      80          40
0277  * :::
0278 */
0279 static int max77620_get_fps_period_reg_value(struct max77620_chip *chip,
0280                          int tperiod)
0281 {
0282     int fps_min_period;
0283     int i;
0284 
0285     switch (chip->chip_id) {
0286     case MAX20024:
0287         fps_min_period = MAX20024_FPS_PERIOD_MIN_US;
0288         break;
0289     case MAX77620:
0290         fps_min_period = MAX77620_FPS_PERIOD_MIN_US;
0291         break;
0292     case MAX77663:
0293         fps_min_period = MAX20024_FPS_PERIOD_MIN_US;
0294         break;
0295     default:
0296         return -EINVAL;
0297     }
0298 
0299     for (i = 0; i < 7; i++) {
0300         if (fps_min_period >= tperiod)
0301             return i;
0302         fps_min_period *= 2;
0303     }
0304 
0305     return i;
0306 }
0307 
0308 /* max77620_config_fps: Configure FPS configuration registers
0309  *          based on platform specific information.
0310  */
0311 static int max77620_config_fps(struct max77620_chip *chip,
0312                    struct device_node *fps_np)
0313 {
0314     struct device *dev = chip->dev;
0315     unsigned int mask = 0, config = 0;
0316     u32 fps_max_period;
0317     u32 param_val;
0318     int tperiod, fps_id;
0319     int ret;
0320     char fps_name[10];
0321 
0322     switch (chip->chip_id) {
0323     case MAX20024:
0324         fps_max_period = MAX20024_FPS_PERIOD_MAX_US;
0325         break;
0326     case MAX77620:
0327         fps_max_period = MAX77620_FPS_PERIOD_MAX_US;
0328         break;
0329     case MAX77663:
0330         fps_max_period = MAX20024_FPS_PERIOD_MAX_US;
0331         break;
0332     default:
0333         return -EINVAL;
0334     }
0335 
0336     for (fps_id = 0; fps_id < MAX77620_FPS_COUNT; fps_id++) {
0337         sprintf(fps_name, "fps%d", fps_id);
0338         if (of_node_name_eq(fps_np, fps_name))
0339             break;
0340     }
0341 
0342     if (fps_id == MAX77620_FPS_COUNT) {
0343         dev_err(dev, "FPS node name %pOFn is not valid\n", fps_np);
0344         return -EINVAL;
0345     }
0346 
0347     ret = of_property_read_u32(fps_np, "maxim,shutdown-fps-time-period-us",
0348                    &param_val);
0349     if (!ret) {
0350         mask |= MAX77620_FPS_TIME_PERIOD_MASK;
0351         chip->shutdown_fps_period[fps_id] = min(param_val,
0352                             fps_max_period);
0353         tperiod = max77620_get_fps_period_reg_value(chip,
0354                 chip->shutdown_fps_period[fps_id]);
0355         config |= tperiod << MAX77620_FPS_TIME_PERIOD_SHIFT;
0356     }
0357 
0358     ret = of_property_read_u32(fps_np, "maxim,suspend-fps-time-period-us",
0359                    &param_val);
0360     if (!ret)
0361         chip->suspend_fps_period[fps_id] = min(param_val,
0362                                fps_max_period);
0363 
0364     ret = of_property_read_u32(fps_np, "maxim,fps-event-source",
0365                    &param_val);
0366     if (!ret) {
0367         if (param_val > 2) {
0368             dev_err(dev, "FPS%d event-source invalid\n", fps_id);
0369             return -EINVAL;
0370         }
0371         mask |= MAX77620_FPS_EN_SRC_MASK;
0372         config |= param_val << MAX77620_FPS_EN_SRC_SHIFT;
0373         if (param_val == 2) {
0374             mask |= MAX77620_FPS_ENFPS_SW_MASK;
0375             config |= MAX77620_FPS_ENFPS_SW;
0376         }
0377     }
0378 
0379     if (!chip->sleep_enable && !chip->enable_global_lpm) {
0380         ret = of_property_read_u32(fps_np,
0381                 "maxim,device-state-on-disabled-event",
0382                 &param_val);
0383         if (!ret) {
0384             if (param_val == 0)
0385                 chip->sleep_enable = true;
0386             else if (param_val == 1)
0387                 chip->enable_global_lpm = true;
0388         }
0389     }
0390 
0391     ret = regmap_update_bits(chip->rmap, MAX77620_REG_FPS_CFG0 + fps_id,
0392                  mask, config);
0393     if (ret < 0) {
0394         dev_err(dev, "Failed to update FPS CFG: %d\n", ret);
0395         return ret;
0396     }
0397 
0398     return 0;
0399 }
0400 
0401 static int max77620_initialise_fps(struct max77620_chip *chip)
0402 {
0403     struct device *dev = chip->dev;
0404     struct device_node *fps_np, *fps_child;
0405     u8 config;
0406     int fps_id;
0407     int ret;
0408 
0409     for (fps_id = 0; fps_id < MAX77620_FPS_COUNT; fps_id++) {
0410         chip->shutdown_fps_period[fps_id] = -1;
0411         chip->suspend_fps_period[fps_id] = -1;
0412     }
0413 
0414     fps_np = of_get_child_by_name(dev->of_node, "fps");
0415     if (!fps_np)
0416         goto skip_fps;
0417 
0418     for_each_child_of_node(fps_np, fps_child) {
0419         ret = max77620_config_fps(chip, fps_child);
0420         if (ret < 0) {
0421             of_node_put(fps_child);
0422             of_node_put(fps_np);
0423             return ret;
0424         }
0425     }
0426     of_node_put(fps_np);
0427 
0428     config = chip->enable_global_lpm ? MAX77620_ONOFFCNFG2_SLP_LPM_MSK : 0;
0429     ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
0430                  MAX77620_ONOFFCNFG2_SLP_LPM_MSK, config);
0431     if (ret < 0) {
0432         dev_err(dev, "Failed to update SLP_LPM: %d\n", ret);
0433         return ret;
0434     }
0435 
0436 skip_fps:
0437     if (chip->chip_id == MAX77663)
0438         return 0;
0439 
0440     /* Enable wake on EN0 pin */
0441     ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
0442                  MAX77620_ONOFFCNFG2_WK_EN0,
0443                  MAX77620_ONOFFCNFG2_WK_EN0);
0444     if (ret < 0) {
0445         dev_err(dev, "Failed to update WK_EN0: %d\n", ret);
0446         return ret;
0447     }
0448 
0449     /* For MAX20024, SLPEN will be POR reset if CLRSE is b11 */
0450     if ((chip->chip_id == MAX20024) && chip->sleep_enable) {
0451         config = MAX77620_ONOFFCNFG1_SLPEN | MAX20024_ONOFFCNFG1_CLRSE;
0452         ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG1,
0453                      config, config);
0454         if (ret < 0) {
0455             dev_err(dev, "Failed to update SLPEN: %d\n", ret);
0456             return ret;
0457         }
0458     }
0459 
0460     return 0;
0461 }
0462 
0463 static int max77620_read_es_version(struct max77620_chip *chip)
0464 {
0465     unsigned int val;
0466     u8 cid_val[6];
0467     int i;
0468     int ret;
0469 
0470     for (i = MAX77620_REG_CID0; i <= MAX77620_REG_CID5; i++) {
0471         ret = regmap_read(chip->rmap, i, &val);
0472         if (ret < 0) {
0473             dev_err(chip->dev, "Failed to read CID: %d\n", ret);
0474             return ret;
0475         }
0476         dev_dbg(chip->dev, "CID%d: 0x%02x\n",
0477             i - MAX77620_REG_CID0, val);
0478         cid_val[i - MAX77620_REG_CID0] = val;
0479     }
0480 
0481     /* CID4 is OTP Version  and CID5 is ES version */
0482     dev_info(chip->dev, "PMIC Version OTP:0x%02X and ES:0x%X\n",
0483          cid_val[4], MAX77620_CID5_DIDM(cid_val[5]));
0484 
0485     return ret;
0486 }
0487 
0488 static void max77620_pm_power_off(void)
0489 {
0490     struct max77620_chip *chip = max77620_scratch;
0491 
0492     regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG1,
0493                MAX77620_ONOFFCNFG1_SFT_RST,
0494                MAX77620_ONOFFCNFG1_SFT_RST);
0495 }
0496 
0497 static int max77620_probe(struct i2c_client *client,
0498               const struct i2c_device_id *id)
0499 {
0500     const struct regmap_config *rmap_config;
0501     struct max77620_chip *chip;
0502     const struct mfd_cell *mfd_cells;
0503     int n_mfd_cells;
0504     bool pm_off;
0505     int ret;
0506 
0507     chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
0508     if (!chip)
0509         return -ENOMEM;
0510 
0511     i2c_set_clientdata(client, chip);
0512     chip->dev = &client->dev;
0513     chip->chip_irq = client->irq;
0514     chip->chip_id = (enum max77620_chip_id)id->driver_data;
0515 
0516     switch (chip->chip_id) {
0517     case MAX77620:
0518         mfd_cells = max77620_children;
0519         n_mfd_cells = ARRAY_SIZE(max77620_children);
0520         rmap_config = &max77620_regmap_config;
0521         break;
0522     case MAX20024:
0523         mfd_cells = max20024_children;
0524         n_mfd_cells = ARRAY_SIZE(max20024_children);
0525         rmap_config = &max20024_regmap_config;
0526         break;
0527     case MAX77663:
0528         mfd_cells = max77663_children;
0529         n_mfd_cells = ARRAY_SIZE(max77663_children);
0530         rmap_config = &max77663_regmap_config;
0531         break;
0532     default:
0533         dev_err(chip->dev, "ChipID is invalid %d\n", chip->chip_id);
0534         return -EINVAL;
0535     }
0536 
0537     chip->rmap = devm_regmap_init_i2c(client, rmap_config);
0538     if (IS_ERR(chip->rmap)) {
0539         ret = PTR_ERR(chip->rmap);
0540         dev_err(chip->dev, "Failed to initialise regmap: %d\n", ret);
0541         return ret;
0542     }
0543 
0544     ret = max77620_read_es_version(chip);
0545     if (ret < 0)
0546         return ret;
0547 
0548     max77620_top_irq_chip.irq_drv_data = chip;
0549     ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq,
0550                        IRQF_ONESHOT | IRQF_SHARED, 0,
0551                        &max77620_top_irq_chip,
0552                        &chip->top_irq_data);
0553     if (ret < 0) {
0554         dev_err(chip->dev, "Failed to add regmap irq: %d\n", ret);
0555         return ret;
0556     }
0557 
0558     ret = max77620_initialise_fps(chip);
0559     if (ret < 0)
0560         return ret;
0561 
0562     ret =  devm_mfd_add_devices(chip->dev, PLATFORM_DEVID_NONE,
0563                     mfd_cells, n_mfd_cells, NULL, 0,
0564                     regmap_irq_get_domain(chip->top_irq_data));
0565     if (ret < 0) {
0566         dev_err(chip->dev, "Failed to add MFD children: %d\n", ret);
0567         return ret;
0568     }
0569 
0570     pm_off = of_device_is_system_power_controller(client->dev.of_node);
0571     if (pm_off && !pm_power_off) {
0572         max77620_scratch = chip;
0573         pm_power_off = max77620_pm_power_off;
0574     }
0575 
0576     return 0;
0577 }
0578 
0579 #ifdef CONFIG_PM_SLEEP
0580 static int max77620_set_fps_period(struct max77620_chip *chip,
0581                    int fps_id, int time_period)
0582 {
0583     int period = max77620_get_fps_period_reg_value(chip, time_period);
0584     int ret;
0585 
0586     ret = regmap_update_bits(chip->rmap, MAX77620_REG_FPS_CFG0 + fps_id,
0587                  MAX77620_FPS_TIME_PERIOD_MASK,
0588                  period << MAX77620_FPS_TIME_PERIOD_SHIFT);
0589     if (ret < 0) {
0590         dev_err(chip->dev, "Failed to update FPS period: %d\n", ret);
0591         return ret;
0592     }
0593 
0594     return 0;
0595 }
0596 
0597 static int max77620_i2c_suspend(struct device *dev)
0598 {
0599     struct max77620_chip *chip = dev_get_drvdata(dev);
0600     struct i2c_client *client = to_i2c_client(dev);
0601     unsigned int config;
0602     int fps;
0603     int ret;
0604 
0605     for (fps = 0; fps < MAX77620_FPS_COUNT; fps++) {
0606         if (chip->suspend_fps_period[fps] < 0)
0607             continue;
0608 
0609         ret = max77620_set_fps_period(chip, fps,
0610                           chip->suspend_fps_period[fps]);
0611         if (ret < 0)
0612             return ret;
0613     }
0614 
0615     /*
0616      * For MAX20024: No need to configure SLPEN on suspend as
0617      * it will be configured on Init.
0618      */
0619     if (chip->chip_id == MAX20024)
0620         goto out;
0621 
0622     config = (chip->sleep_enable) ? MAX77620_ONOFFCNFG1_SLPEN : 0;
0623     ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG1,
0624                  MAX77620_ONOFFCNFG1_SLPEN,
0625                  config);
0626     if (ret < 0) {
0627         dev_err(dev, "Failed to configure sleep in suspend: %d\n", ret);
0628         return ret;
0629     }
0630 
0631     if (chip->chip_id == MAX77663)
0632         goto out;
0633 
0634     /* Disable WK_EN0 */
0635     ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
0636                  MAX77620_ONOFFCNFG2_WK_EN0, 0);
0637     if (ret < 0) {
0638         dev_err(dev, "Failed to configure WK_EN in suspend: %d\n", ret);
0639         return ret;
0640     }
0641 
0642 out:
0643     disable_irq(client->irq);
0644 
0645     return 0;
0646 }
0647 
0648 static int max77620_i2c_resume(struct device *dev)
0649 {
0650     struct max77620_chip *chip = dev_get_drvdata(dev);
0651     struct i2c_client *client = to_i2c_client(dev);
0652     int ret;
0653     int fps;
0654 
0655     for (fps = 0; fps < MAX77620_FPS_COUNT; fps++) {
0656         if (chip->shutdown_fps_period[fps] < 0)
0657             continue;
0658 
0659         ret = max77620_set_fps_period(chip, fps,
0660                           chip->shutdown_fps_period[fps]);
0661         if (ret < 0)
0662             return ret;
0663     }
0664 
0665     /*
0666      * For MAX20024: No need to configure WKEN0 on resume as
0667      * it is configured on Init.
0668      */
0669     if (chip->chip_id == MAX20024 || chip->chip_id == MAX77663)
0670         goto out;
0671 
0672     /* Enable WK_EN0 */
0673     ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
0674                  MAX77620_ONOFFCNFG2_WK_EN0,
0675                  MAX77620_ONOFFCNFG2_WK_EN0);
0676     if (ret < 0) {
0677         dev_err(dev, "Failed to configure WK_EN0 n resume: %d\n", ret);
0678         return ret;
0679     }
0680 
0681 out:
0682     enable_irq(client->irq);
0683 
0684     return 0;
0685 }
0686 #endif
0687 
0688 static const struct i2c_device_id max77620_id[] = {
0689     {"max77620", MAX77620},
0690     {"max20024", MAX20024},
0691     {"max77663", MAX77663},
0692     {},
0693 };
0694 
0695 static const struct dev_pm_ops max77620_pm_ops = {
0696     SET_SYSTEM_SLEEP_PM_OPS(max77620_i2c_suspend, max77620_i2c_resume)
0697 };
0698 
0699 static struct i2c_driver max77620_driver = {
0700     .driver = {
0701         .name = "max77620",
0702         .pm = &max77620_pm_ops,
0703     },
0704     .probe = max77620_probe,
0705     .id_table = max77620_id,
0706 };
0707 builtin_i2c_driver(max77620_driver);