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