15b1c2028SLaxman Dewangan /* 25b1c2028SLaxman Dewangan * Maxim MAX77620 Regulator driver 35b1c2028SLaxman Dewangan * 45b1c2028SLaxman Dewangan * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 55b1c2028SLaxman Dewangan * 65b1c2028SLaxman Dewangan * Author: Mallikarjun Kasoju <mkasoju@nvidia.com> 75b1c2028SLaxman Dewangan * Laxman Dewangan <ldewangan@nvidia.com> 85b1c2028SLaxman Dewangan * 95b1c2028SLaxman Dewangan * This program is free software; you can redistribute it and/or modify it 105b1c2028SLaxman Dewangan * under the terms and conditions of the GNU General Public License, 115b1c2028SLaxman Dewangan * version 2, as published by the Free Software Foundation. 125b1c2028SLaxman Dewangan */ 135b1c2028SLaxman Dewangan 145b1c2028SLaxman Dewangan #include <linux/init.h> 155b1c2028SLaxman Dewangan #include <linux/mfd/max77620.h> 165b1c2028SLaxman Dewangan #include <linux/module.h> 175b1c2028SLaxman Dewangan #include <linux/of.h> 185b1c2028SLaxman Dewangan #include <linux/platform_device.h> 195b1c2028SLaxman Dewangan #include <linux/regmap.h> 205b1c2028SLaxman Dewangan #include <linux/regulator/driver.h> 215b1c2028SLaxman Dewangan #include <linux/regulator/machine.h> 225b1c2028SLaxman Dewangan #include <linux/regulator/of_regulator.h> 235b1c2028SLaxman Dewangan 245b1c2028SLaxman Dewangan #define max77620_rails(_name) "max77620-"#_name 255b1c2028SLaxman Dewangan 265b1c2028SLaxman Dewangan /* Power Mode */ 275b1c2028SLaxman Dewangan #define MAX77620_POWER_MODE_NORMAL 3 285b1c2028SLaxman Dewangan #define MAX77620_POWER_MODE_LPM 2 295b1c2028SLaxman Dewangan #define MAX77620_POWER_MODE_GLPM 1 305b1c2028SLaxman Dewangan #define MAX77620_POWER_MODE_DISABLE 0 315b1c2028SLaxman Dewangan 325b1c2028SLaxman Dewangan /* SD Slew Rate */ 335b1c2028SLaxman Dewangan #define MAX77620_SD_SR_13_75 0 345b1c2028SLaxman Dewangan #define MAX77620_SD_SR_27_5 1 355b1c2028SLaxman Dewangan #define MAX77620_SD_SR_55 2 365b1c2028SLaxman Dewangan #define MAX77620_SD_SR_100 3 375b1c2028SLaxman Dewangan 385b1c2028SLaxman Dewangan enum max77620_regulators { 395b1c2028SLaxman Dewangan MAX77620_REGULATOR_ID_SD0, 405b1c2028SLaxman Dewangan MAX77620_REGULATOR_ID_SD1, 415b1c2028SLaxman Dewangan MAX77620_REGULATOR_ID_SD2, 425b1c2028SLaxman Dewangan MAX77620_REGULATOR_ID_SD3, 435b1c2028SLaxman Dewangan MAX77620_REGULATOR_ID_SD4, 445b1c2028SLaxman Dewangan MAX77620_REGULATOR_ID_LDO0, 455b1c2028SLaxman Dewangan MAX77620_REGULATOR_ID_LDO1, 465b1c2028SLaxman Dewangan MAX77620_REGULATOR_ID_LDO2, 475b1c2028SLaxman Dewangan MAX77620_REGULATOR_ID_LDO3, 485b1c2028SLaxman Dewangan MAX77620_REGULATOR_ID_LDO4, 495b1c2028SLaxman Dewangan MAX77620_REGULATOR_ID_LDO5, 505b1c2028SLaxman Dewangan MAX77620_REGULATOR_ID_LDO6, 515b1c2028SLaxman Dewangan MAX77620_REGULATOR_ID_LDO7, 525b1c2028SLaxman Dewangan MAX77620_REGULATOR_ID_LDO8, 535b1c2028SLaxman Dewangan MAX77620_NUM_REGS, 545b1c2028SLaxman Dewangan }; 555b1c2028SLaxman Dewangan 565b1c2028SLaxman Dewangan /* Regulator types */ 575b1c2028SLaxman Dewangan enum max77620_regulator_type { 585b1c2028SLaxman Dewangan MAX77620_REGULATOR_TYPE_SD, 595b1c2028SLaxman Dewangan MAX77620_REGULATOR_TYPE_LDO_N, 605b1c2028SLaxman Dewangan MAX77620_REGULATOR_TYPE_LDO_P, 615b1c2028SLaxman Dewangan }; 625b1c2028SLaxman Dewangan 635b1c2028SLaxman Dewangan struct max77620_regulator_info { 645b1c2028SLaxman Dewangan u8 type; 655b1c2028SLaxman Dewangan u8 fps_addr; 665b1c2028SLaxman Dewangan u8 volt_addr; 675b1c2028SLaxman Dewangan u8 cfg_addr; 685b1c2028SLaxman Dewangan u8 power_mode_mask; 695b1c2028SLaxman Dewangan u8 power_mode_shift; 705b1c2028SLaxman Dewangan u8 remote_sense_addr; 715b1c2028SLaxman Dewangan u8 remote_sense_mask; 725b1c2028SLaxman Dewangan struct regulator_desc desc; 735b1c2028SLaxman Dewangan }; 745b1c2028SLaxman Dewangan 755b1c2028SLaxman Dewangan struct max77620_regulator_pdata { 765b1c2028SLaxman Dewangan struct regulator_init_data *reg_idata; 775b1c2028SLaxman Dewangan int active_fps_src; 785b1c2028SLaxman Dewangan int active_fps_pd_slot; 795b1c2028SLaxman Dewangan int active_fps_pu_slot; 805b1c2028SLaxman Dewangan int suspend_fps_src; 815b1c2028SLaxman Dewangan int suspend_fps_pd_slot; 825b1c2028SLaxman Dewangan int suspend_fps_pu_slot; 835b1c2028SLaxman Dewangan int current_mode; 845aa43599SLaxman Dewangan int ramp_rate_setting; 855b1c2028SLaxman Dewangan }; 865b1c2028SLaxman Dewangan 875b1c2028SLaxman Dewangan struct max77620_regulator { 885b1c2028SLaxman Dewangan struct device *dev; 895b1c2028SLaxman Dewangan struct regmap *rmap; 905b1c2028SLaxman Dewangan struct max77620_regulator_info *rinfo[MAX77620_NUM_REGS]; 915b1c2028SLaxman Dewangan struct max77620_regulator_pdata reg_pdata[MAX77620_NUM_REGS]; 925b1c2028SLaxman Dewangan int enable_power_mode[MAX77620_NUM_REGS]; 935b1c2028SLaxman Dewangan int current_power_mode[MAX77620_NUM_REGS]; 945b1c2028SLaxman Dewangan int active_fps_src[MAX77620_NUM_REGS]; 955b1c2028SLaxman Dewangan }; 965b1c2028SLaxman Dewangan 975b1c2028SLaxman Dewangan #define fps_src_name(fps_src) \ 985b1c2028SLaxman Dewangan (fps_src == MAX77620_FPS_SRC_0 ? "FPS_SRC_0" : \ 995b1c2028SLaxman Dewangan fps_src == MAX77620_FPS_SRC_1 ? "FPS_SRC_1" : \ 1005b1c2028SLaxman Dewangan fps_src == MAX77620_FPS_SRC_2 ? "FPS_SRC_2" : "FPS_SRC_NONE") 1015b1c2028SLaxman Dewangan 1025b1c2028SLaxman Dewangan static int max77620_regulator_get_fps_src(struct max77620_regulator *pmic, 1035b1c2028SLaxman Dewangan int id) 1045b1c2028SLaxman Dewangan { 1055b1c2028SLaxman Dewangan struct max77620_regulator_info *rinfo = pmic->rinfo[id]; 1065b1c2028SLaxman Dewangan unsigned int val; 1075b1c2028SLaxman Dewangan int ret; 1085b1c2028SLaxman Dewangan 1095b1c2028SLaxman Dewangan ret = regmap_read(pmic->rmap, rinfo->fps_addr, &val); 1105b1c2028SLaxman Dewangan if (ret < 0) { 1115b1c2028SLaxman Dewangan dev_err(pmic->dev, "Reg 0x%02x read failed %d\n", 1125b1c2028SLaxman Dewangan rinfo->fps_addr, ret); 1135b1c2028SLaxman Dewangan return ret; 1145b1c2028SLaxman Dewangan } 1155b1c2028SLaxman Dewangan 1165b1c2028SLaxman Dewangan return (val & MAX77620_FPS_SRC_MASK) >> MAX77620_FPS_SRC_SHIFT; 1175b1c2028SLaxman Dewangan } 1185b1c2028SLaxman Dewangan 1195b1c2028SLaxman Dewangan static int max77620_regulator_set_fps_src(struct max77620_regulator *pmic, 1205b1c2028SLaxman Dewangan int fps_src, int id) 1215b1c2028SLaxman Dewangan { 1225b1c2028SLaxman Dewangan struct max77620_regulator_info *rinfo = pmic->rinfo[id]; 1235b1c2028SLaxman Dewangan unsigned int val; 1245b1c2028SLaxman Dewangan int ret; 1255b1c2028SLaxman Dewangan 12691ff811fSVenkat Reddy Talla if (!rinfo) 12791ff811fSVenkat Reddy Talla return 0; 12891ff811fSVenkat Reddy Talla 1295b1c2028SLaxman Dewangan switch (fps_src) { 1305b1c2028SLaxman Dewangan case MAX77620_FPS_SRC_0: 1315b1c2028SLaxman Dewangan case MAX77620_FPS_SRC_1: 1325b1c2028SLaxman Dewangan case MAX77620_FPS_SRC_2: 1335b1c2028SLaxman Dewangan case MAX77620_FPS_SRC_NONE: 1345b1c2028SLaxman Dewangan break; 1355b1c2028SLaxman Dewangan 1365b1c2028SLaxman Dewangan case MAX77620_FPS_SRC_DEF: 1375b1c2028SLaxman Dewangan ret = regmap_read(pmic->rmap, rinfo->fps_addr, &val); 1385b1c2028SLaxman Dewangan if (ret < 0) { 1395b1c2028SLaxman Dewangan dev_err(pmic->dev, "Reg 0x%02x read failed %d\n", 1405b1c2028SLaxman Dewangan rinfo->fps_addr, ret); 1415b1c2028SLaxman Dewangan return ret; 1425b1c2028SLaxman Dewangan } 1435b1c2028SLaxman Dewangan ret = (val & MAX77620_FPS_SRC_MASK) >> MAX77620_FPS_SRC_SHIFT; 1445b1c2028SLaxman Dewangan pmic->active_fps_src[id] = ret; 1455b1c2028SLaxman Dewangan return 0; 1465b1c2028SLaxman Dewangan 1475b1c2028SLaxman Dewangan default: 1485b1c2028SLaxman Dewangan dev_err(pmic->dev, "Invalid FPS %d for regulator %d\n", 1495b1c2028SLaxman Dewangan fps_src, id); 1505b1c2028SLaxman Dewangan return -EINVAL; 1515b1c2028SLaxman Dewangan } 1525b1c2028SLaxman Dewangan 1535b1c2028SLaxman Dewangan ret = regmap_update_bits(pmic->rmap, rinfo->fps_addr, 1545b1c2028SLaxman Dewangan MAX77620_FPS_SRC_MASK, 1555b1c2028SLaxman Dewangan fps_src << MAX77620_FPS_SRC_SHIFT); 1565b1c2028SLaxman Dewangan if (ret < 0) { 1575b1c2028SLaxman Dewangan dev_err(pmic->dev, "Reg 0x%02x update failed %d\n", 1585b1c2028SLaxman Dewangan rinfo->fps_addr, ret); 1595b1c2028SLaxman Dewangan return ret; 1605b1c2028SLaxman Dewangan } 1615b1c2028SLaxman Dewangan pmic->active_fps_src[id] = fps_src; 1625b1c2028SLaxman Dewangan 1635b1c2028SLaxman Dewangan return 0; 1645b1c2028SLaxman Dewangan } 1655b1c2028SLaxman Dewangan 1665b1c2028SLaxman Dewangan static int max77620_regulator_set_fps_slots(struct max77620_regulator *pmic, 1675b1c2028SLaxman Dewangan int id, bool is_suspend) 1685b1c2028SLaxman Dewangan { 1695b1c2028SLaxman Dewangan struct max77620_regulator_pdata *rpdata = &pmic->reg_pdata[id]; 1705b1c2028SLaxman Dewangan struct max77620_regulator_info *rinfo = pmic->rinfo[id]; 1715b1c2028SLaxman Dewangan unsigned int val = 0; 1725b1c2028SLaxman Dewangan unsigned int mask = 0; 1735b1c2028SLaxman Dewangan int pu = rpdata->active_fps_pu_slot; 1745b1c2028SLaxman Dewangan int pd = rpdata->active_fps_pd_slot; 1755b1c2028SLaxman Dewangan int ret = 0; 1765b1c2028SLaxman Dewangan 17791ff811fSVenkat Reddy Talla if (!rinfo) 17891ff811fSVenkat Reddy Talla return 0; 17991ff811fSVenkat Reddy Talla 1805b1c2028SLaxman Dewangan if (is_suspend) { 1815b1c2028SLaxman Dewangan pu = rpdata->suspend_fps_pu_slot; 1825b1c2028SLaxman Dewangan pd = rpdata->suspend_fps_pd_slot; 1835b1c2028SLaxman Dewangan } 1845b1c2028SLaxman Dewangan 1855b1c2028SLaxman Dewangan /* FPS power up period setting */ 1865b1c2028SLaxman Dewangan if (pu >= 0) { 1875b1c2028SLaxman Dewangan val |= (pu << MAX77620_FPS_PU_PERIOD_SHIFT); 1885b1c2028SLaxman Dewangan mask |= MAX77620_FPS_PU_PERIOD_MASK; 1895b1c2028SLaxman Dewangan } 1905b1c2028SLaxman Dewangan 1915b1c2028SLaxman Dewangan /* FPS power down period setting */ 1925b1c2028SLaxman Dewangan if (pd >= 0) { 1935b1c2028SLaxman Dewangan val |= (pd << MAX77620_FPS_PD_PERIOD_SHIFT); 1945b1c2028SLaxman Dewangan mask |= MAX77620_FPS_PD_PERIOD_MASK; 1955b1c2028SLaxman Dewangan } 1965b1c2028SLaxman Dewangan 1975b1c2028SLaxman Dewangan if (mask) { 1985b1c2028SLaxman Dewangan ret = regmap_update_bits(pmic->rmap, rinfo->fps_addr, 1995b1c2028SLaxman Dewangan mask, val); 2005b1c2028SLaxman Dewangan if (ret < 0) { 2015b1c2028SLaxman Dewangan dev_err(pmic->dev, "Reg 0x%02x update failed: %d\n", 2025b1c2028SLaxman Dewangan rinfo->fps_addr, ret); 2035b1c2028SLaxman Dewangan return ret; 2045b1c2028SLaxman Dewangan } 2055b1c2028SLaxman Dewangan } 2065b1c2028SLaxman Dewangan 2075b1c2028SLaxman Dewangan return ret; 2085b1c2028SLaxman Dewangan } 2095b1c2028SLaxman Dewangan 2105b1c2028SLaxman Dewangan static int max77620_regulator_set_power_mode(struct max77620_regulator *pmic, 2115b1c2028SLaxman Dewangan int power_mode, int id) 2125b1c2028SLaxman Dewangan { 2135b1c2028SLaxman Dewangan struct max77620_regulator_info *rinfo = pmic->rinfo[id]; 2145b1c2028SLaxman Dewangan u8 mask = rinfo->power_mode_mask; 2155b1c2028SLaxman Dewangan u8 shift = rinfo->power_mode_shift; 2165b1c2028SLaxman Dewangan u8 addr; 2175b1c2028SLaxman Dewangan int ret; 2185b1c2028SLaxman Dewangan 2195b1c2028SLaxman Dewangan switch (rinfo->type) { 2205b1c2028SLaxman Dewangan case MAX77620_REGULATOR_TYPE_SD: 2215b1c2028SLaxman Dewangan addr = rinfo->cfg_addr; 2225b1c2028SLaxman Dewangan break; 2235b1c2028SLaxman Dewangan default: 2245b1c2028SLaxman Dewangan addr = rinfo->volt_addr; 2255b1c2028SLaxman Dewangan break; 2265b1c2028SLaxman Dewangan } 2275b1c2028SLaxman Dewangan 2285b1c2028SLaxman Dewangan ret = regmap_update_bits(pmic->rmap, addr, mask, power_mode << shift); 2295b1c2028SLaxman Dewangan if (ret < 0) { 2305b1c2028SLaxman Dewangan dev_err(pmic->dev, "Regulator %d mode set failed: %d\n", 2315b1c2028SLaxman Dewangan id, ret); 2325b1c2028SLaxman Dewangan return ret; 2335b1c2028SLaxman Dewangan } 2345b1c2028SLaxman Dewangan pmic->current_power_mode[id] = power_mode; 2355b1c2028SLaxman Dewangan 2365b1c2028SLaxman Dewangan return ret; 2375b1c2028SLaxman Dewangan } 2385b1c2028SLaxman Dewangan 2395b1c2028SLaxman Dewangan static int max77620_regulator_get_power_mode(struct max77620_regulator *pmic, 2405b1c2028SLaxman Dewangan int id) 2415b1c2028SLaxman Dewangan { 2425b1c2028SLaxman Dewangan struct max77620_regulator_info *rinfo = pmic->rinfo[id]; 2435b1c2028SLaxman Dewangan unsigned int val, addr; 2445b1c2028SLaxman Dewangan u8 mask = rinfo->power_mode_mask; 2455b1c2028SLaxman Dewangan u8 shift = rinfo->power_mode_shift; 2465b1c2028SLaxman Dewangan int ret; 2475b1c2028SLaxman Dewangan 2485b1c2028SLaxman Dewangan switch (rinfo->type) { 2495b1c2028SLaxman Dewangan case MAX77620_REGULATOR_TYPE_SD: 2505b1c2028SLaxman Dewangan addr = rinfo->cfg_addr; 2515b1c2028SLaxman Dewangan break; 2525b1c2028SLaxman Dewangan default: 2535b1c2028SLaxman Dewangan addr = rinfo->volt_addr; 2545b1c2028SLaxman Dewangan break; 2555b1c2028SLaxman Dewangan } 2565b1c2028SLaxman Dewangan 2575b1c2028SLaxman Dewangan ret = regmap_read(pmic->rmap, addr, &val); 2585b1c2028SLaxman Dewangan if (ret < 0) { 2595b1c2028SLaxman Dewangan dev_err(pmic->dev, "Regulator %d: Reg 0x%02x read failed: %d\n", 2605b1c2028SLaxman Dewangan id, addr, ret); 2615b1c2028SLaxman Dewangan return ret; 2625b1c2028SLaxman Dewangan } 2635b1c2028SLaxman Dewangan 2645b1c2028SLaxman Dewangan return (val & mask) >> shift; 2655b1c2028SLaxman Dewangan } 2665b1c2028SLaxman Dewangan 2675b1c2028SLaxman Dewangan static int max77620_read_slew_rate(struct max77620_regulator *pmic, int id) 2685b1c2028SLaxman Dewangan { 2695b1c2028SLaxman Dewangan struct max77620_regulator_info *rinfo = pmic->rinfo[id]; 2705b1c2028SLaxman Dewangan unsigned int rval; 2715b1c2028SLaxman Dewangan int slew_rate; 2725b1c2028SLaxman Dewangan int ret; 2735b1c2028SLaxman Dewangan 2745b1c2028SLaxman Dewangan ret = regmap_read(pmic->rmap, rinfo->cfg_addr, &rval); 2755b1c2028SLaxman Dewangan if (ret < 0) { 2765b1c2028SLaxman Dewangan dev_err(pmic->dev, "Register 0x%02x read failed: %d\n", 2775b1c2028SLaxman Dewangan rinfo->cfg_addr, ret); 2785b1c2028SLaxman Dewangan return ret; 2795b1c2028SLaxman Dewangan } 2805b1c2028SLaxman Dewangan 281aad76f74SAxel Lin switch (rinfo->type) { 282aad76f74SAxel Lin case MAX77620_REGULATOR_TYPE_SD: 2835b1c2028SLaxman Dewangan slew_rate = (rval >> MAX77620_SD_SR_SHIFT) & 0x3; 2845b1c2028SLaxman Dewangan switch (slew_rate) { 2855b1c2028SLaxman Dewangan case 0: 2865b1c2028SLaxman Dewangan slew_rate = 13750; 2875b1c2028SLaxman Dewangan break; 2885b1c2028SLaxman Dewangan case 1: 2895b1c2028SLaxman Dewangan slew_rate = 27500; 2905b1c2028SLaxman Dewangan break; 2915b1c2028SLaxman Dewangan case 2: 2925b1c2028SLaxman Dewangan slew_rate = 55000; 2935b1c2028SLaxman Dewangan break; 2945b1c2028SLaxman Dewangan case 3: 2955b1c2028SLaxman Dewangan slew_rate = 100000; 2965b1c2028SLaxman Dewangan break; 2975b1c2028SLaxman Dewangan } 2985b1c2028SLaxman Dewangan rinfo->desc.ramp_delay = slew_rate; 2995b1c2028SLaxman Dewangan break; 3005b1c2028SLaxman Dewangan default: 3015b1c2028SLaxman Dewangan slew_rate = rval & 0x1; 3025b1c2028SLaxman Dewangan switch (slew_rate) { 3035b1c2028SLaxman Dewangan case 0: 3045b1c2028SLaxman Dewangan slew_rate = 100000; 3055b1c2028SLaxman Dewangan break; 3065b1c2028SLaxman Dewangan case 1: 3075b1c2028SLaxman Dewangan slew_rate = 5000; 3085b1c2028SLaxman Dewangan break; 3095b1c2028SLaxman Dewangan } 3105b1c2028SLaxman Dewangan rinfo->desc.ramp_delay = slew_rate; 3115b1c2028SLaxman Dewangan break; 3125b1c2028SLaxman Dewangan } 3135b1c2028SLaxman Dewangan 3145b1c2028SLaxman Dewangan return 0; 3155b1c2028SLaxman Dewangan } 3165b1c2028SLaxman Dewangan 3175aa43599SLaxman Dewangan static int max77620_set_slew_rate(struct max77620_regulator *pmic, int id, 3185aa43599SLaxman Dewangan int slew_rate) 3195aa43599SLaxman Dewangan { 3205aa43599SLaxman Dewangan struct max77620_regulator_info *rinfo = pmic->rinfo[id]; 3215aa43599SLaxman Dewangan unsigned int val; 3225aa43599SLaxman Dewangan int ret; 3235aa43599SLaxman Dewangan u8 mask; 3245aa43599SLaxman Dewangan 3255aa43599SLaxman Dewangan if (rinfo->type == MAX77620_REGULATOR_TYPE_SD) { 3265aa43599SLaxman Dewangan if (slew_rate <= 13750) 3275aa43599SLaxman Dewangan val = 0; 3285aa43599SLaxman Dewangan else if (slew_rate <= 27500) 3295aa43599SLaxman Dewangan val = 1; 3305aa43599SLaxman Dewangan else if (slew_rate <= 55000) 3315aa43599SLaxman Dewangan val = 2; 3325aa43599SLaxman Dewangan else 3335aa43599SLaxman Dewangan val = 3; 3345aa43599SLaxman Dewangan val <<= MAX77620_SD_SR_SHIFT; 3355aa43599SLaxman Dewangan mask = MAX77620_SD_SR_MASK; 3365aa43599SLaxman Dewangan } else { 3375aa43599SLaxman Dewangan if (slew_rate <= 5000) 3385aa43599SLaxman Dewangan val = 1; 3395aa43599SLaxman Dewangan else 3405aa43599SLaxman Dewangan val = 0; 3415aa43599SLaxman Dewangan mask = MAX77620_LDO_SLEW_RATE_MASK; 3425aa43599SLaxman Dewangan } 3435aa43599SLaxman Dewangan 3445aa43599SLaxman Dewangan ret = regmap_update_bits(pmic->rmap, rinfo->cfg_addr, mask, val); 3455aa43599SLaxman Dewangan if (ret < 0) { 3465aa43599SLaxman Dewangan dev_err(pmic->dev, "Regulator %d slew rate set failed: %d\n", 3475aa43599SLaxman Dewangan id, ret); 3485aa43599SLaxman Dewangan return ret; 3495aa43599SLaxman Dewangan } 3505aa43599SLaxman Dewangan 3515aa43599SLaxman Dewangan return 0; 3525aa43599SLaxman Dewangan } 3535aa43599SLaxman Dewangan 3545b1c2028SLaxman Dewangan static int max77620_init_pmic(struct max77620_regulator *pmic, int id) 3555b1c2028SLaxman Dewangan { 3565b1c2028SLaxman Dewangan struct max77620_regulator_pdata *rpdata = &pmic->reg_pdata[id]; 3575b1c2028SLaxman Dewangan int ret; 3585b1c2028SLaxman Dewangan 3595b1c2028SLaxman Dewangan /* Update power mode */ 3605b1c2028SLaxman Dewangan ret = max77620_regulator_get_power_mode(pmic, id); 3615b1c2028SLaxman Dewangan if (ret < 0) 3625b1c2028SLaxman Dewangan return ret; 3635b1c2028SLaxman Dewangan 3645b1c2028SLaxman Dewangan pmic->current_power_mode[id] = ret; 3655b1c2028SLaxman Dewangan pmic->enable_power_mode[id] = MAX77620_POWER_MODE_NORMAL; 3665b1c2028SLaxman Dewangan 3675b1c2028SLaxman Dewangan if (rpdata->active_fps_src == MAX77620_FPS_SRC_DEF) { 3685b1c2028SLaxman Dewangan ret = max77620_regulator_get_fps_src(pmic, id); 3695b1c2028SLaxman Dewangan if (ret < 0) 3705b1c2028SLaxman Dewangan return ret; 3715b1c2028SLaxman Dewangan rpdata->active_fps_src = ret; 3725b1c2028SLaxman Dewangan } 3735b1c2028SLaxman Dewangan 3745b1c2028SLaxman Dewangan /* If rails are externally control of FPS then enable it always. */ 3755b1c2028SLaxman Dewangan if (rpdata->active_fps_src == MAX77620_FPS_SRC_NONE) { 3765b1c2028SLaxman Dewangan ret = max77620_regulator_set_power_mode(pmic, 3775b1c2028SLaxman Dewangan pmic->enable_power_mode[id], id); 3785b1c2028SLaxman Dewangan if (ret < 0) 3795b1c2028SLaxman Dewangan return ret; 3805b1c2028SLaxman Dewangan } else { 3815b1c2028SLaxman Dewangan if (pmic->current_power_mode[id] != 3825b1c2028SLaxman Dewangan pmic->enable_power_mode[id]) { 3835b1c2028SLaxman Dewangan ret = max77620_regulator_set_power_mode(pmic, 3845b1c2028SLaxman Dewangan pmic->enable_power_mode[id], id); 3855b1c2028SLaxman Dewangan if (ret < 0) 3865b1c2028SLaxman Dewangan return ret; 3875b1c2028SLaxman Dewangan } 3885b1c2028SLaxman Dewangan } 3895b1c2028SLaxman Dewangan 3905b1c2028SLaxman Dewangan ret = max77620_regulator_set_fps_src(pmic, rpdata->active_fps_src, id); 3915b1c2028SLaxman Dewangan if (ret < 0) 3925b1c2028SLaxman Dewangan return ret; 3935b1c2028SLaxman Dewangan 3945b1c2028SLaxman Dewangan ret = max77620_regulator_set_fps_slots(pmic, id, false); 3955b1c2028SLaxman Dewangan if (ret < 0) 3965b1c2028SLaxman Dewangan return ret; 3975b1c2028SLaxman Dewangan 3985aa43599SLaxman Dewangan if (rpdata->ramp_rate_setting) { 3995aa43599SLaxman Dewangan ret = max77620_set_slew_rate(pmic, id, 4005aa43599SLaxman Dewangan rpdata->ramp_rate_setting); 4015aa43599SLaxman Dewangan if (ret < 0) 4025aa43599SLaxman Dewangan return ret; 4035aa43599SLaxman Dewangan } 4045aa43599SLaxman Dewangan 4055b1c2028SLaxman Dewangan return 0; 4065b1c2028SLaxman Dewangan } 4075b1c2028SLaxman Dewangan 4085b1c2028SLaxman Dewangan static int max77620_regulator_enable(struct regulator_dev *rdev) 4095b1c2028SLaxman Dewangan { 4105b1c2028SLaxman Dewangan struct max77620_regulator *pmic = rdev_get_drvdata(rdev); 4115b1c2028SLaxman Dewangan int id = rdev_get_id(rdev); 4125b1c2028SLaxman Dewangan 4135b1c2028SLaxman Dewangan if (pmic->active_fps_src[id] != MAX77620_FPS_SRC_NONE) 4145b1c2028SLaxman Dewangan return 0; 4155b1c2028SLaxman Dewangan 4165b1c2028SLaxman Dewangan return max77620_regulator_set_power_mode(pmic, 4175b1c2028SLaxman Dewangan pmic->enable_power_mode[id], id); 4185b1c2028SLaxman Dewangan } 4195b1c2028SLaxman Dewangan 4205b1c2028SLaxman Dewangan static int max77620_regulator_disable(struct regulator_dev *rdev) 4215b1c2028SLaxman Dewangan { 4225b1c2028SLaxman Dewangan struct max77620_regulator *pmic = rdev_get_drvdata(rdev); 4235b1c2028SLaxman Dewangan int id = rdev_get_id(rdev); 4245b1c2028SLaxman Dewangan 4255b1c2028SLaxman Dewangan if (pmic->active_fps_src[id] != MAX77620_FPS_SRC_NONE) 4265b1c2028SLaxman Dewangan return 0; 4275b1c2028SLaxman Dewangan 4285b1c2028SLaxman Dewangan return max77620_regulator_set_power_mode(pmic, 4295b1c2028SLaxman Dewangan MAX77620_POWER_MODE_DISABLE, id); 4305b1c2028SLaxman Dewangan } 4315b1c2028SLaxman Dewangan 4325b1c2028SLaxman Dewangan static int max77620_regulator_is_enabled(struct regulator_dev *rdev) 4335b1c2028SLaxman Dewangan { 4345b1c2028SLaxman Dewangan struct max77620_regulator *pmic = rdev_get_drvdata(rdev); 4355b1c2028SLaxman Dewangan int id = rdev_get_id(rdev); 4365b1c2028SLaxman Dewangan int ret = 1; 4375b1c2028SLaxman Dewangan 4385b1c2028SLaxman Dewangan if (pmic->active_fps_src[id] != MAX77620_FPS_SRC_NONE) 4395b1c2028SLaxman Dewangan return 1; 4405b1c2028SLaxman Dewangan 4415b1c2028SLaxman Dewangan ret = max77620_regulator_get_power_mode(pmic, id); 4425b1c2028SLaxman Dewangan if (ret < 0) 4435b1c2028SLaxman Dewangan return ret; 4445b1c2028SLaxman Dewangan 4455b1c2028SLaxman Dewangan if (ret != MAX77620_POWER_MODE_DISABLE) 4465b1c2028SLaxman Dewangan return 1; 4475b1c2028SLaxman Dewangan 4485b1c2028SLaxman Dewangan return 0; 4495b1c2028SLaxman Dewangan } 4505b1c2028SLaxman Dewangan 4515b1c2028SLaxman Dewangan static int max77620_regulator_set_mode(struct regulator_dev *rdev, 4525b1c2028SLaxman Dewangan unsigned int mode) 4535b1c2028SLaxman Dewangan { 4545b1c2028SLaxman Dewangan struct max77620_regulator *pmic = rdev_get_drvdata(rdev); 4555b1c2028SLaxman Dewangan int id = rdev_get_id(rdev); 4565b1c2028SLaxman Dewangan struct max77620_regulator_info *rinfo = pmic->rinfo[id]; 4575b1c2028SLaxman Dewangan struct max77620_regulator_pdata *rpdata = &pmic->reg_pdata[id]; 4585b1c2028SLaxman Dewangan bool fpwm = false; 4595b1c2028SLaxman Dewangan int power_mode; 4605b1c2028SLaxman Dewangan int ret; 4615b1c2028SLaxman Dewangan u8 val; 4625b1c2028SLaxman Dewangan 4635b1c2028SLaxman Dewangan switch (mode) { 4645b1c2028SLaxman Dewangan case REGULATOR_MODE_FAST: 4655b1c2028SLaxman Dewangan fpwm = true; 4665b1c2028SLaxman Dewangan power_mode = MAX77620_POWER_MODE_NORMAL; 4675b1c2028SLaxman Dewangan break; 4685b1c2028SLaxman Dewangan 4695b1c2028SLaxman Dewangan case REGULATOR_MODE_NORMAL: 4705b1c2028SLaxman Dewangan power_mode = MAX77620_POWER_MODE_NORMAL; 4715b1c2028SLaxman Dewangan break; 4725b1c2028SLaxman Dewangan 4735b1c2028SLaxman Dewangan case REGULATOR_MODE_IDLE: 4745b1c2028SLaxman Dewangan power_mode = MAX77620_POWER_MODE_LPM; 4755b1c2028SLaxman Dewangan break; 4765b1c2028SLaxman Dewangan 4775b1c2028SLaxman Dewangan default: 4785b1c2028SLaxman Dewangan dev_err(pmic->dev, "Regulator %d mode %d is invalid\n", 4795b1c2028SLaxman Dewangan id, mode); 4805b1c2028SLaxman Dewangan return -EINVAL; 4815b1c2028SLaxman Dewangan } 4825b1c2028SLaxman Dewangan 4835b1c2028SLaxman Dewangan if (rinfo->type != MAX77620_REGULATOR_TYPE_SD) 4845b1c2028SLaxman Dewangan goto skip_fpwm; 4855b1c2028SLaxman Dewangan 4865b1c2028SLaxman Dewangan val = (fpwm) ? MAX77620_SD_FPWM_MASK : 0; 4875b1c2028SLaxman Dewangan ret = regmap_update_bits(pmic->rmap, rinfo->cfg_addr, 4885b1c2028SLaxman Dewangan MAX77620_SD_FPWM_MASK, val); 4895b1c2028SLaxman Dewangan if (ret < 0) { 4905b1c2028SLaxman Dewangan dev_err(pmic->dev, "Reg 0x%02x update failed: %d\n", 4915b1c2028SLaxman Dewangan rinfo->cfg_addr, ret); 4925b1c2028SLaxman Dewangan return ret; 4935b1c2028SLaxman Dewangan } 4945b1c2028SLaxman Dewangan rpdata->current_mode = mode; 4955b1c2028SLaxman Dewangan 4965b1c2028SLaxman Dewangan skip_fpwm: 4975b1c2028SLaxman Dewangan ret = max77620_regulator_set_power_mode(pmic, power_mode, id); 4985b1c2028SLaxman Dewangan if (ret < 0) 4995b1c2028SLaxman Dewangan return ret; 5005b1c2028SLaxman Dewangan 5015b1c2028SLaxman Dewangan pmic->enable_power_mode[id] = power_mode; 5025b1c2028SLaxman Dewangan 5035b1c2028SLaxman Dewangan return 0; 5045b1c2028SLaxman Dewangan } 5055b1c2028SLaxman Dewangan 5065b1c2028SLaxman Dewangan static unsigned int max77620_regulator_get_mode(struct regulator_dev *rdev) 5075b1c2028SLaxman Dewangan { 5085b1c2028SLaxman Dewangan struct max77620_regulator *pmic = rdev_get_drvdata(rdev); 5095b1c2028SLaxman Dewangan int id = rdev_get_id(rdev); 5105b1c2028SLaxman Dewangan struct max77620_regulator_info *rinfo = pmic->rinfo[id]; 5115b1c2028SLaxman Dewangan int fpwm = 0; 5125b1c2028SLaxman Dewangan int ret; 5135b1c2028SLaxman Dewangan int pm_mode, reg_mode; 5145b1c2028SLaxman Dewangan unsigned int val; 5155b1c2028SLaxman Dewangan 5165b1c2028SLaxman Dewangan ret = max77620_regulator_get_power_mode(pmic, id); 5175b1c2028SLaxman Dewangan if (ret < 0) 5185b1c2028SLaxman Dewangan return 0; 5195b1c2028SLaxman Dewangan 5205b1c2028SLaxman Dewangan pm_mode = ret; 5215b1c2028SLaxman Dewangan 5225b1c2028SLaxman Dewangan if (rinfo->type == MAX77620_REGULATOR_TYPE_SD) { 5235b1c2028SLaxman Dewangan ret = regmap_read(pmic->rmap, rinfo->cfg_addr, &val); 5245b1c2028SLaxman Dewangan if (ret < 0) { 5255b1c2028SLaxman Dewangan dev_err(pmic->dev, "Reg 0x%02x read failed: %d\n", 5265b1c2028SLaxman Dewangan rinfo->cfg_addr, ret); 5275b1c2028SLaxman Dewangan return ret; 5285b1c2028SLaxman Dewangan } 5295b1c2028SLaxman Dewangan fpwm = !!(val & MAX77620_SD_FPWM_MASK); 5305b1c2028SLaxman Dewangan } 5315b1c2028SLaxman Dewangan 5325b1c2028SLaxman Dewangan switch (pm_mode) { 5335b1c2028SLaxman Dewangan case MAX77620_POWER_MODE_NORMAL: 5345b1c2028SLaxman Dewangan case MAX77620_POWER_MODE_DISABLE: 5355b1c2028SLaxman Dewangan if (fpwm) 5365b1c2028SLaxman Dewangan reg_mode = REGULATOR_MODE_FAST; 5375b1c2028SLaxman Dewangan else 5385b1c2028SLaxman Dewangan reg_mode = REGULATOR_MODE_NORMAL; 5395b1c2028SLaxman Dewangan break; 5405b1c2028SLaxman Dewangan case MAX77620_POWER_MODE_LPM: 5415b1c2028SLaxman Dewangan case MAX77620_POWER_MODE_GLPM: 5425b1c2028SLaxman Dewangan reg_mode = REGULATOR_MODE_IDLE; 5435b1c2028SLaxman Dewangan break; 5445b1c2028SLaxman Dewangan default: 5455b1c2028SLaxman Dewangan return 0; 5465b1c2028SLaxman Dewangan } 5475b1c2028SLaxman Dewangan 5485b1c2028SLaxman Dewangan return reg_mode; 5495b1c2028SLaxman Dewangan } 5505b1c2028SLaxman Dewangan 5515b1c2028SLaxman Dewangan static int max77620_regulator_set_ramp_delay(struct regulator_dev *rdev, 5525b1c2028SLaxman Dewangan int ramp_delay) 5535b1c2028SLaxman Dewangan { 5545b1c2028SLaxman Dewangan struct max77620_regulator *pmic = rdev_get_drvdata(rdev); 5555b1c2028SLaxman Dewangan int id = rdev_get_id(rdev); 5565aa43599SLaxman Dewangan struct max77620_regulator_pdata *rpdata = &pmic->reg_pdata[id]; 5575b1c2028SLaxman Dewangan 5585aa43599SLaxman Dewangan /* Device specific ramp rate setting tells that platform has 5595aa43599SLaxman Dewangan * different ramp rate from advertised value. In this case, 5605aa43599SLaxman Dewangan * do not configure anything and just return success. 5615aa43599SLaxman Dewangan */ 5625aa43599SLaxman Dewangan if (rpdata->ramp_rate_setting) 5635aa43599SLaxman Dewangan return 0; 5645b1c2028SLaxman Dewangan 5655aa43599SLaxman Dewangan return max77620_set_slew_rate(pmic, id, ramp_delay); 5665b1c2028SLaxman Dewangan } 5675b1c2028SLaxman Dewangan 5685b1c2028SLaxman Dewangan static int max77620_of_parse_cb(struct device_node *np, 5695b1c2028SLaxman Dewangan const struct regulator_desc *desc, 5705b1c2028SLaxman Dewangan struct regulator_config *config) 5715b1c2028SLaxman Dewangan { 5725b1c2028SLaxman Dewangan struct max77620_regulator *pmic = config->driver_data; 5735b1c2028SLaxman Dewangan struct max77620_regulator_pdata *rpdata = &pmic->reg_pdata[desc->id]; 5745b1c2028SLaxman Dewangan u32 pval; 5755b1c2028SLaxman Dewangan int ret; 5765b1c2028SLaxman Dewangan 5775b1c2028SLaxman Dewangan ret = of_property_read_u32(np, "maxim,active-fps-source", &pval); 5785b1c2028SLaxman Dewangan rpdata->active_fps_src = (!ret) ? pval : MAX77620_FPS_SRC_DEF; 5795b1c2028SLaxman Dewangan 5805b1c2028SLaxman Dewangan ret = of_property_read_u32(np, "maxim,active-fps-power-up-slot", &pval); 5815b1c2028SLaxman Dewangan rpdata->active_fps_pu_slot = (!ret) ? pval : -1; 5825b1c2028SLaxman Dewangan 5835b1c2028SLaxman Dewangan ret = of_property_read_u32( 5845b1c2028SLaxman Dewangan np, "maxim,active-fps-power-down-slot", &pval); 5855b1c2028SLaxman Dewangan rpdata->active_fps_pd_slot = (!ret) ? pval : -1; 5865b1c2028SLaxman Dewangan 5875b1c2028SLaxman Dewangan ret = of_property_read_u32(np, "maxim,suspend-fps-source", &pval); 5885b1c2028SLaxman Dewangan rpdata->suspend_fps_src = (!ret) ? pval : -1; 5895b1c2028SLaxman Dewangan 5905b1c2028SLaxman Dewangan ret = of_property_read_u32( 5915b1c2028SLaxman Dewangan np, "maxim,suspend-fps-power-up-slot", &pval); 5925b1c2028SLaxman Dewangan rpdata->suspend_fps_pu_slot = (!ret) ? pval : -1; 5935b1c2028SLaxman Dewangan 5945b1c2028SLaxman Dewangan ret = of_property_read_u32( 5955b1c2028SLaxman Dewangan np, "maxim,suspend-fps-power-down-slot", &pval); 5965b1c2028SLaxman Dewangan rpdata->suspend_fps_pd_slot = (!ret) ? pval : -1; 5975b1c2028SLaxman Dewangan 5985aa43599SLaxman Dewangan ret = of_property_read_u32(np, "maxim,ramp-rate-setting", &pval); 5995aa43599SLaxman Dewangan rpdata->ramp_rate_setting = (!ret) ? pval : 0; 6005aa43599SLaxman Dewangan 6015b1c2028SLaxman Dewangan return max77620_init_pmic(pmic, desc->id); 6025b1c2028SLaxman Dewangan } 6035b1c2028SLaxman Dewangan 6045b1c2028SLaxman Dewangan static struct regulator_ops max77620_regulator_ops = { 6055b1c2028SLaxman Dewangan .is_enabled = max77620_regulator_is_enabled, 6065b1c2028SLaxman Dewangan .enable = max77620_regulator_enable, 6075b1c2028SLaxman Dewangan .disable = max77620_regulator_disable, 6085b1c2028SLaxman Dewangan .list_voltage = regulator_list_voltage_linear, 6095b1c2028SLaxman Dewangan .map_voltage = regulator_map_voltage_linear, 6105b1c2028SLaxman Dewangan .get_voltage_sel = regulator_get_voltage_sel_regmap, 6115b1c2028SLaxman Dewangan .set_voltage_sel = regulator_set_voltage_sel_regmap, 6125b1c2028SLaxman Dewangan .set_mode = max77620_regulator_set_mode, 6135b1c2028SLaxman Dewangan .get_mode = max77620_regulator_get_mode, 6145b1c2028SLaxman Dewangan .set_ramp_delay = max77620_regulator_set_ramp_delay, 6155b1c2028SLaxman Dewangan .set_voltage_time_sel = regulator_set_voltage_time_sel, 61651817f46SLaxman Dewangan .set_active_discharge = regulator_set_active_discharge_regmap, 6175b1c2028SLaxman Dewangan }; 6185b1c2028SLaxman Dewangan 6195b1c2028SLaxman Dewangan #define MAX77620_SD_CNF2_ROVS_EN_NONE 0 6205b1c2028SLaxman Dewangan #define RAIL_SD(_id, _name, _sname, _volt_mask, _min_uV, _max_uV, \ 6215b1c2028SLaxman Dewangan _step_uV, _rs_add, _rs_mask) \ 6225b1c2028SLaxman Dewangan [MAX77620_REGULATOR_ID_##_id] = { \ 6235b1c2028SLaxman Dewangan .type = MAX77620_REGULATOR_TYPE_SD, \ 6245b1c2028SLaxman Dewangan .volt_addr = MAX77620_REG_##_id, \ 6255b1c2028SLaxman Dewangan .cfg_addr = MAX77620_REG_##_id##_CFG, \ 6265b1c2028SLaxman Dewangan .fps_addr = MAX77620_REG_FPS_##_id, \ 6275b1c2028SLaxman Dewangan .remote_sense_addr = _rs_add, \ 6285b1c2028SLaxman Dewangan .remote_sense_mask = MAX77620_SD_CNF2_ROVS_EN_##_rs_mask, \ 6295b1c2028SLaxman Dewangan .power_mode_mask = MAX77620_SD_POWER_MODE_MASK, \ 6305b1c2028SLaxman Dewangan .power_mode_shift = MAX77620_SD_POWER_MODE_SHIFT, \ 6315b1c2028SLaxman Dewangan .desc = { \ 6325b1c2028SLaxman Dewangan .name = max77620_rails(_name), \ 6335b1c2028SLaxman Dewangan .of_match = of_match_ptr(#_name), \ 6345b1c2028SLaxman Dewangan .regulators_node = of_match_ptr("regulators"), \ 6355b1c2028SLaxman Dewangan .of_parse_cb = max77620_of_parse_cb, \ 6365b1c2028SLaxman Dewangan .supply_name = _sname, \ 6375b1c2028SLaxman Dewangan .id = MAX77620_REGULATOR_ID_##_id, \ 6385b1c2028SLaxman Dewangan .ops = &max77620_regulator_ops, \ 6395b1c2028SLaxman Dewangan .n_voltages = ((_max_uV - _min_uV) / _step_uV) + 1, \ 6405b1c2028SLaxman Dewangan .min_uV = _min_uV, \ 6415b1c2028SLaxman Dewangan .uV_step = _step_uV, \ 6425b1c2028SLaxman Dewangan .enable_time = 500, \ 6435b1c2028SLaxman Dewangan .vsel_mask = MAX77620_##_volt_mask##_VOLT_MASK, \ 6445b1c2028SLaxman Dewangan .vsel_reg = MAX77620_REG_##_id, \ 64551817f46SLaxman Dewangan .active_discharge_off = 0, \ 64651817f46SLaxman Dewangan .active_discharge_on = MAX77620_SD_CFG1_ADE_ENABLE, \ 64751817f46SLaxman Dewangan .active_discharge_mask = MAX77620_SD_CFG1_ADE_MASK, \ 64851817f46SLaxman Dewangan .active_discharge_reg = MAX77620_REG_##_id##_CFG, \ 6495b1c2028SLaxman Dewangan .type = REGULATOR_VOLTAGE, \ 6505b1c2028SLaxman Dewangan }, \ 6515b1c2028SLaxman Dewangan } 6525b1c2028SLaxman Dewangan 6535b1c2028SLaxman Dewangan #define RAIL_LDO(_id, _name, _sname, _type, _min_uV, _max_uV, _step_uV) \ 6545b1c2028SLaxman Dewangan [MAX77620_REGULATOR_ID_##_id] = { \ 6555b1c2028SLaxman Dewangan .type = MAX77620_REGULATOR_TYPE_LDO_##_type, \ 6565b1c2028SLaxman Dewangan .volt_addr = MAX77620_REG_##_id##_CFG, \ 6575b1c2028SLaxman Dewangan .cfg_addr = MAX77620_REG_##_id##_CFG2, \ 6585b1c2028SLaxman Dewangan .fps_addr = MAX77620_REG_FPS_##_id, \ 6595b1c2028SLaxman Dewangan .remote_sense_addr = 0xFF, \ 6605b1c2028SLaxman Dewangan .power_mode_mask = MAX77620_LDO_POWER_MODE_MASK, \ 6615b1c2028SLaxman Dewangan .power_mode_shift = MAX77620_LDO_POWER_MODE_SHIFT, \ 6625b1c2028SLaxman Dewangan .desc = { \ 6635b1c2028SLaxman Dewangan .name = max77620_rails(_name), \ 6645b1c2028SLaxman Dewangan .of_match = of_match_ptr(#_name), \ 6655b1c2028SLaxman Dewangan .regulators_node = of_match_ptr("regulators"), \ 6665b1c2028SLaxman Dewangan .of_parse_cb = max77620_of_parse_cb, \ 6675b1c2028SLaxman Dewangan .supply_name = _sname, \ 6685b1c2028SLaxman Dewangan .id = MAX77620_REGULATOR_ID_##_id, \ 6695b1c2028SLaxman Dewangan .ops = &max77620_regulator_ops, \ 6705b1c2028SLaxman Dewangan .n_voltages = ((_max_uV - _min_uV) / _step_uV) + 1, \ 6715b1c2028SLaxman Dewangan .min_uV = _min_uV, \ 6725b1c2028SLaxman Dewangan .uV_step = _step_uV, \ 6735b1c2028SLaxman Dewangan .enable_time = 500, \ 6745b1c2028SLaxman Dewangan .vsel_mask = MAX77620_LDO_VOLT_MASK, \ 6755b1c2028SLaxman Dewangan .vsel_reg = MAX77620_REG_##_id##_CFG, \ 67651817f46SLaxman Dewangan .active_discharge_off = 0, \ 67751817f46SLaxman Dewangan .active_discharge_on = MAX77620_LDO_CFG2_ADE_ENABLE, \ 67851817f46SLaxman Dewangan .active_discharge_mask = MAX77620_LDO_CFG2_ADE_MASK, \ 67951817f46SLaxman Dewangan .active_discharge_reg = MAX77620_REG_##_id##_CFG2, \ 6805b1c2028SLaxman Dewangan .type = REGULATOR_VOLTAGE, \ 6815b1c2028SLaxman Dewangan }, \ 6825b1c2028SLaxman Dewangan } 6835b1c2028SLaxman Dewangan 6845b1c2028SLaxman Dewangan static struct max77620_regulator_info max77620_regs_info[MAX77620_NUM_REGS] = { 6855b1c2028SLaxman Dewangan RAIL_SD(SD0, sd0, "in-sd0", SD0, 600000, 1400000, 12500, 0x22, SD0), 6865b1c2028SLaxman Dewangan RAIL_SD(SD1, sd1, "in-sd1", SD1, 600000, 1550000, 12500, 0x22, SD1), 6875b1c2028SLaxman Dewangan RAIL_SD(SD2, sd2, "in-sd2", SDX, 600000, 3787500, 12500, 0xFF, NONE), 6885b1c2028SLaxman Dewangan RAIL_SD(SD3, sd3, "in-sd3", SDX, 600000, 3787500, 12500, 0xFF, NONE), 6895b1c2028SLaxman Dewangan 6905b1c2028SLaxman Dewangan RAIL_LDO(LDO0, ldo0, "in-ldo0-1", N, 800000, 2375000, 25000), 6915b1c2028SLaxman Dewangan RAIL_LDO(LDO1, ldo1, "in-ldo0-1", N, 800000, 2375000, 25000), 6925b1c2028SLaxman Dewangan RAIL_LDO(LDO2, ldo2, "in-ldo2", P, 800000, 3950000, 50000), 6935b1c2028SLaxman Dewangan RAIL_LDO(LDO3, ldo3, "in-ldo3-5", P, 800000, 3950000, 50000), 6945b1c2028SLaxman Dewangan RAIL_LDO(LDO4, ldo4, "in-ldo4-6", P, 800000, 1587500, 12500), 6955b1c2028SLaxman Dewangan RAIL_LDO(LDO5, ldo5, "in-ldo3-5", P, 800000, 3950000, 50000), 6965b1c2028SLaxman Dewangan RAIL_LDO(LDO6, ldo6, "in-ldo4-6", P, 800000, 3950000, 50000), 6975b1c2028SLaxman Dewangan RAIL_LDO(LDO7, ldo7, "in-ldo7-8", N, 800000, 3950000, 50000), 6985b1c2028SLaxman Dewangan RAIL_LDO(LDO8, ldo8, "in-ldo7-8", N, 800000, 3950000, 50000), 6995b1c2028SLaxman Dewangan }; 7005b1c2028SLaxman Dewangan 7015b1c2028SLaxman Dewangan static struct max77620_regulator_info max20024_regs_info[MAX77620_NUM_REGS] = { 7025b1c2028SLaxman Dewangan RAIL_SD(SD0, sd0, "in-sd0", SD0, 800000, 1587500, 12500, 0x22, SD0), 7035b1c2028SLaxman Dewangan RAIL_SD(SD1, sd1, "in-sd1", SD1, 600000, 3387500, 12500, 0x22, SD1), 7045b1c2028SLaxman Dewangan RAIL_SD(SD2, sd2, "in-sd2", SDX, 600000, 3787500, 12500, 0xFF, NONE), 7055b1c2028SLaxman Dewangan RAIL_SD(SD3, sd3, "in-sd3", SDX, 600000, 3787500, 12500, 0xFF, NONE), 7065b1c2028SLaxman Dewangan RAIL_SD(SD4, sd4, "in-sd4", SDX, 600000, 3787500, 12500, 0xFF, NONE), 7075b1c2028SLaxman Dewangan 7085b1c2028SLaxman Dewangan RAIL_LDO(LDO0, ldo0, "in-ldo0-1", N, 800000, 2375000, 25000), 7095b1c2028SLaxman Dewangan RAIL_LDO(LDO1, ldo1, "in-ldo0-1", N, 800000, 2375000, 25000), 7105b1c2028SLaxman Dewangan RAIL_LDO(LDO2, ldo2, "in-ldo2", P, 800000, 3950000, 50000), 7115b1c2028SLaxman Dewangan RAIL_LDO(LDO3, ldo3, "in-ldo3-5", P, 800000, 3950000, 50000), 7125b1c2028SLaxman Dewangan RAIL_LDO(LDO4, ldo4, "in-ldo4-6", P, 800000, 1587500, 12500), 7135b1c2028SLaxman Dewangan RAIL_LDO(LDO5, ldo5, "in-ldo3-5", P, 800000, 3950000, 50000), 7145b1c2028SLaxman Dewangan RAIL_LDO(LDO6, ldo6, "in-ldo4-6", P, 800000, 3950000, 50000), 7155b1c2028SLaxman Dewangan RAIL_LDO(LDO7, ldo7, "in-ldo7-8", N, 800000, 3950000, 50000), 7165b1c2028SLaxman Dewangan RAIL_LDO(LDO8, ldo8, "in-ldo7-8", N, 800000, 3950000, 50000), 7175b1c2028SLaxman Dewangan }; 7185b1c2028SLaxman Dewangan 7195b1c2028SLaxman Dewangan static int max77620_regulator_probe(struct platform_device *pdev) 7205b1c2028SLaxman Dewangan { 7215b1c2028SLaxman Dewangan struct max77620_chip *max77620_chip = dev_get_drvdata(pdev->dev.parent); 7225b1c2028SLaxman Dewangan struct max77620_regulator_info *rinfo; 7235b1c2028SLaxman Dewangan struct device *dev = &pdev->dev; 7245b1c2028SLaxman Dewangan struct regulator_config config = { }; 7255b1c2028SLaxman Dewangan struct max77620_regulator *pmic; 7265b1c2028SLaxman Dewangan int ret = 0; 7275b1c2028SLaxman Dewangan int id; 7285b1c2028SLaxman Dewangan 7295b1c2028SLaxman Dewangan pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL); 7305b1c2028SLaxman Dewangan if (!pmic) 7315b1c2028SLaxman Dewangan return -ENOMEM; 7325b1c2028SLaxman Dewangan 7335b1c2028SLaxman Dewangan platform_set_drvdata(pdev, pmic); 7345b1c2028SLaxman Dewangan pmic->dev = dev; 7355b1c2028SLaxman Dewangan pmic->rmap = max77620_chip->rmap; 7365b1c2028SLaxman Dewangan if (!dev->of_node) 7375b1c2028SLaxman Dewangan dev->of_node = pdev->dev.parent->of_node; 7385b1c2028SLaxman Dewangan 7395b1c2028SLaxman Dewangan switch (max77620_chip->chip_id) { 7405b1c2028SLaxman Dewangan case MAX77620: 7415b1c2028SLaxman Dewangan rinfo = max77620_regs_info; 7425b1c2028SLaxman Dewangan break; 7435b1c2028SLaxman Dewangan default: 7445b1c2028SLaxman Dewangan rinfo = max20024_regs_info; 7455b1c2028SLaxman Dewangan break; 7465b1c2028SLaxman Dewangan } 7475b1c2028SLaxman Dewangan 7485b1c2028SLaxman Dewangan config.regmap = pmic->rmap; 7495b1c2028SLaxman Dewangan config.dev = dev; 7505b1c2028SLaxman Dewangan config.driver_data = pmic; 7515b1c2028SLaxman Dewangan 7525b1c2028SLaxman Dewangan for (id = 0; id < MAX77620_NUM_REGS; id++) { 7535b1c2028SLaxman Dewangan struct regulator_dev *rdev; 7545b1c2028SLaxman Dewangan struct regulator_desc *rdesc; 7555b1c2028SLaxman Dewangan 7565b1c2028SLaxman Dewangan if ((max77620_chip->chip_id == MAX77620) && 7575b1c2028SLaxman Dewangan (id == MAX77620_REGULATOR_ID_SD4)) 7585b1c2028SLaxman Dewangan continue; 7595b1c2028SLaxman Dewangan 7605b1c2028SLaxman Dewangan rdesc = &rinfo[id].desc; 7615b1c2028SLaxman Dewangan pmic->rinfo[id] = &max77620_regs_info[id]; 7625b1c2028SLaxman Dewangan pmic->enable_power_mode[id] = MAX77620_POWER_MODE_NORMAL; 7635b1c2028SLaxman Dewangan 7645b1c2028SLaxman Dewangan ret = max77620_read_slew_rate(pmic, id); 7655b1c2028SLaxman Dewangan if (ret < 0) 7665b1c2028SLaxman Dewangan return ret; 7675b1c2028SLaxman Dewangan 7685b1c2028SLaxman Dewangan rdev = devm_regulator_register(dev, rdesc, &config); 7695b1c2028SLaxman Dewangan if (IS_ERR(rdev)) { 7705b1c2028SLaxman Dewangan ret = PTR_ERR(rdev); 7715b1c2028SLaxman Dewangan dev_err(dev, "Regulator registration %s failed: %d\n", 7725b1c2028SLaxman Dewangan rdesc->name, ret); 7735b1c2028SLaxman Dewangan return ret; 7745b1c2028SLaxman Dewangan } 7755b1c2028SLaxman Dewangan } 7765b1c2028SLaxman Dewangan 7775b1c2028SLaxman Dewangan return 0; 7785b1c2028SLaxman Dewangan } 7795b1c2028SLaxman Dewangan 7805b1c2028SLaxman Dewangan #ifdef CONFIG_PM_SLEEP 7815b1c2028SLaxman Dewangan static int max77620_regulator_suspend(struct device *dev) 7825b1c2028SLaxman Dewangan { 7835b1c2028SLaxman Dewangan struct max77620_regulator *pmic = dev_get_drvdata(dev); 7845b1c2028SLaxman Dewangan struct max77620_regulator_pdata *reg_pdata; 7855b1c2028SLaxman Dewangan int id; 7865b1c2028SLaxman Dewangan 7875b1c2028SLaxman Dewangan for (id = 0; id < MAX77620_NUM_REGS; id++) { 7885b1c2028SLaxman Dewangan reg_pdata = &pmic->reg_pdata[id]; 7895b1c2028SLaxman Dewangan 7905b1c2028SLaxman Dewangan max77620_regulator_set_fps_slots(pmic, id, true); 7915b1c2028SLaxman Dewangan if (reg_pdata->suspend_fps_src < 0) 7925b1c2028SLaxman Dewangan continue; 7935b1c2028SLaxman Dewangan 7945b1c2028SLaxman Dewangan max77620_regulator_set_fps_src(pmic, reg_pdata->suspend_fps_src, 7955b1c2028SLaxman Dewangan id); 7965b1c2028SLaxman Dewangan } 7975b1c2028SLaxman Dewangan 7985b1c2028SLaxman Dewangan return 0; 7995b1c2028SLaxman Dewangan } 8005b1c2028SLaxman Dewangan 8015b1c2028SLaxman Dewangan static int max77620_regulator_resume(struct device *dev) 8025b1c2028SLaxman Dewangan { 8035b1c2028SLaxman Dewangan struct max77620_regulator *pmic = dev_get_drvdata(dev); 8045b1c2028SLaxman Dewangan struct max77620_regulator_pdata *reg_pdata; 8055b1c2028SLaxman Dewangan int id; 8065b1c2028SLaxman Dewangan 8075b1c2028SLaxman Dewangan for (id = 0; id < MAX77620_NUM_REGS; id++) { 8085b1c2028SLaxman Dewangan reg_pdata = &pmic->reg_pdata[id]; 8095b1c2028SLaxman Dewangan 8105b1c2028SLaxman Dewangan max77620_regulator_set_fps_slots(pmic, id, false); 8115b1c2028SLaxman Dewangan if (reg_pdata->active_fps_src < 0) 8125b1c2028SLaxman Dewangan continue; 8135b1c2028SLaxman Dewangan max77620_regulator_set_fps_src(pmic, reg_pdata->active_fps_src, 8145b1c2028SLaxman Dewangan id); 8155b1c2028SLaxman Dewangan } 8165b1c2028SLaxman Dewangan 8175b1c2028SLaxman Dewangan return 0; 8185b1c2028SLaxman Dewangan } 8195b1c2028SLaxman Dewangan #endif 8205b1c2028SLaxman Dewangan 8215b1c2028SLaxman Dewangan static const struct dev_pm_ops max77620_regulator_pm_ops = { 8225b1c2028SLaxman Dewangan SET_SYSTEM_SLEEP_PM_OPS(max77620_regulator_suspend, 8235b1c2028SLaxman Dewangan max77620_regulator_resume) 8245b1c2028SLaxman Dewangan }; 8255b1c2028SLaxman Dewangan 8265b1c2028SLaxman Dewangan static const struct platform_device_id max77620_regulator_devtype[] = { 8275b1c2028SLaxman Dewangan { .name = "max77620-pmic", }, 8285b1c2028SLaxman Dewangan { .name = "max20024-pmic", }, 8295b1c2028SLaxman Dewangan {}, 8305b1c2028SLaxman Dewangan }; 8315b1c2028SLaxman Dewangan MODULE_DEVICE_TABLE(platform, max77620_regulator_devtype); 8325b1c2028SLaxman Dewangan 8335b1c2028SLaxman Dewangan static struct platform_driver max77620_regulator_driver = { 8345b1c2028SLaxman Dewangan .probe = max77620_regulator_probe, 8355b1c2028SLaxman Dewangan .id_table = max77620_regulator_devtype, 8365b1c2028SLaxman Dewangan .driver = { 8375b1c2028SLaxman Dewangan .name = "max77620-pmic", 8385b1c2028SLaxman Dewangan .pm = &max77620_regulator_pm_ops, 8395b1c2028SLaxman Dewangan }, 8405b1c2028SLaxman Dewangan }; 8415b1c2028SLaxman Dewangan 8425b1c2028SLaxman Dewangan module_platform_driver(max77620_regulator_driver); 8435b1c2028SLaxman Dewangan 8445b1c2028SLaxman Dewangan MODULE_DESCRIPTION("MAX77620/MAX20024 regulator driver"); 8455b1c2028SLaxman Dewangan MODULE_AUTHOR("Mallikarjun Kasoju <mkasoju@nvidia.com>"); 8465b1c2028SLaxman Dewangan MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); 8475b1c2028SLaxman Dewangan MODULE_LICENSE("GPL v2"); 848