1e634cf4eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
25928f538SLaxman Dewangan /*
3f1e5ecc5SRamona Alexandra Nechita  * max8973-regulator.c -- Maxim max8973A
45928f538SLaxman Dewangan  *
5f1e5ecc5SRamona Alexandra Nechita  * Regulator driver for MAXIM 8973A DC-DC step-down switching regulator.
65928f538SLaxman Dewangan  *
75928f538SLaxman Dewangan  * Copyright (c) 2012, NVIDIA Corporation.
85928f538SLaxman Dewangan  *
95928f538SLaxman Dewangan  * Author: Laxman Dewangan <ldewangan@nvidia.com>
105928f538SLaxman Dewangan  */
115928f538SLaxman Dewangan 
125928f538SLaxman Dewangan #include <linux/kernel.h>
135928f538SLaxman Dewangan #include <linux/module.h>
145928f538SLaxman Dewangan #include <linux/init.h>
155928f538SLaxman Dewangan #include <linux/err.h>
1642dc3023SGuennadi Liakhovetski #include <linux/of.h>
170f7d6eceSLaxman Dewangan #include <linux/of_device.h>
185928f538SLaxman Dewangan #include <linux/platform_device.h>
195928f538SLaxman Dewangan #include <linux/regulator/driver.h>
205928f538SLaxman Dewangan #include <linux/regulator/machine.h>
215928f538SLaxman Dewangan #include <linux/regulator/max8973-regulator.h>
2242dc3023SGuennadi Liakhovetski #include <linux/regulator/of_regulator.h>
235928f538SLaxman Dewangan #include <linux/gpio.h>
24e7d2be69SLinus Walleij #include <linux/gpio/consumer.h>
25c2ffa973SLaxman Dewangan #include <linux/of_gpio.h>
265928f538SLaxman Dewangan #include <linux/i2c.h>
275928f538SLaxman Dewangan #include <linux/slab.h>
285928f538SLaxman Dewangan #include <linux/regmap.h>
29d2d5437bSLaxman Dewangan #include <linux/thermal.h>
30d2d5437bSLaxman Dewangan #include <linux/irq.h>
31d2d5437bSLaxman Dewangan #include <linux/interrupt.h>
325928f538SLaxman Dewangan 
335928f538SLaxman Dewangan /* Register definitions */
345928f538SLaxman Dewangan #define MAX8973_VOUT					0x0
355928f538SLaxman Dewangan #define MAX8973_VOUT_DVS				0x1
365928f538SLaxman Dewangan #define MAX8973_CONTROL1				0x2
375928f538SLaxman Dewangan #define MAX8973_CONTROL2				0x3
385928f538SLaxman Dewangan #define MAX8973_CHIPID1					0x4
395928f538SLaxman Dewangan #define MAX8973_CHIPID2					0x5
405928f538SLaxman Dewangan 
415928f538SLaxman Dewangan #define MAX8973_MAX_VOUT_REG				2
425928f538SLaxman Dewangan 
435928f538SLaxman Dewangan /* MAX8973_VOUT */
445928f538SLaxman Dewangan #define MAX8973_VOUT_ENABLE				BIT(7)
455928f538SLaxman Dewangan #define MAX8973_VOUT_MASK				0x7F
465928f538SLaxman Dewangan 
475928f538SLaxman Dewangan /* MAX8973_VOUT_DVS */
485928f538SLaxman Dewangan #define MAX8973_DVS_VOUT_MASK				0x7F
495928f538SLaxman Dewangan 
505928f538SLaxman Dewangan /* MAX8973_CONTROL1 */
515928f538SLaxman Dewangan #define MAX8973_SNS_ENABLE				BIT(7)
525928f538SLaxman Dewangan #define MAX8973_FPWM_EN_M				BIT(6)
535928f538SLaxman Dewangan #define MAX8973_NFSR_ENABLE				BIT(5)
545928f538SLaxman Dewangan #define MAX8973_AD_ENABLE				BIT(4)
555928f538SLaxman Dewangan #define MAX8973_BIAS_ENABLE				BIT(3)
565928f538SLaxman Dewangan #define MAX8973_FREQSHIFT_9PER				BIT(2)
575928f538SLaxman Dewangan 
585928f538SLaxman Dewangan #define MAX8973_RAMP_12mV_PER_US			0x0
595928f538SLaxman Dewangan #define MAX8973_RAMP_25mV_PER_US			0x1
605928f538SLaxman Dewangan #define MAX8973_RAMP_50mV_PER_US			0x2
615928f538SLaxman Dewangan #define MAX8973_RAMP_200mV_PER_US			0x3
623064c1f3SLaxman Dewangan #define MAX8973_RAMP_MASK				0x3
635928f538SLaxman Dewangan 
645928f538SLaxman Dewangan /* MAX8973_CONTROL2 */
655928f538SLaxman Dewangan #define MAX8973_WDTMR_ENABLE				BIT(6)
665928f538SLaxman Dewangan #define MAX8973_DISCH_ENBABLE				BIT(5)
675928f538SLaxman Dewangan #define MAX8973_FT_ENABLE				BIT(4)
68d2d5437bSLaxman Dewangan #define MAX77621_T_JUNCTION_120				BIT(7)
695928f538SLaxman Dewangan 
70ffaab991SLaxman Dewangan #define MAX8973_CKKADV_TRIP_MASK			0xC
715928f538SLaxman Dewangan #define MAX8973_CKKADV_TRIP_DISABLE			0xC
725928f538SLaxman Dewangan #define MAX8973_CKKADV_TRIP_75mV_PER_US			0x0
735928f538SLaxman Dewangan #define MAX8973_CKKADV_TRIP_150mV_PER_US		0x4
745928f538SLaxman Dewangan #define MAX8973_CKKADV_TRIP_75mV_PER_US_HIST_DIS	0x8
755928f538SLaxman Dewangan #define MAX8973_CONTROL_CLKADV_TRIP_MASK		0x00030000
765928f538SLaxman Dewangan 
775928f538SLaxman Dewangan #define MAX8973_INDUCTOR_MIN_30_PER			0x0
785928f538SLaxman Dewangan #define MAX8973_INDUCTOR_NOMINAL			0x1
795928f538SLaxman Dewangan #define MAX8973_INDUCTOR_PLUS_30_PER			0x2
805928f538SLaxman Dewangan #define MAX8973_INDUCTOR_PLUS_60_PER			0x3
815928f538SLaxman Dewangan #define MAX8973_CONTROL_INDUCTOR_VALUE_MASK		0x00300000
825928f538SLaxman Dewangan 
835928f538SLaxman Dewangan #define MAX8973_MIN_VOLATGE				606250
845928f538SLaxman Dewangan #define MAX8973_MAX_VOLATGE				1400000
855928f538SLaxman Dewangan #define MAX8973_VOLATGE_STEP				6250
865928f538SLaxman Dewangan #define MAX8973_BUCK_N_VOLTAGE				0x80
875928f538SLaxman Dewangan 
88d2d5437bSLaxman Dewangan #define MAX77621_CHIPID_TJINT_S				BIT(0)
89d2d5437bSLaxman Dewangan 
90d2d5437bSLaxman Dewangan #define MAX77621_NORMAL_OPERATING_TEMP			100000
91d2d5437bSLaxman Dewangan #define MAX77621_TJINT_WARNING_TEMP_120			120000
92d2d5437bSLaxman Dewangan #define MAX77621_TJINT_WARNING_TEMP_140			140000
93d2d5437bSLaxman Dewangan 
940f7d6eceSLaxman Dewangan enum device_id {
950f7d6eceSLaxman Dewangan 	MAX8973,
960f7d6eceSLaxman Dewangan 	MAX77621
970f7d6eceSLaxman Dewangan };
980f7d6eceSLaxman Dewangan 
995928f538SLaxman Dewangan /* Maxim 8973 chip information */
1005928f538SLaxman Dewangan struct max8973_chip {
1015928f538SLaxman Dewangan 	struct device *dev;
1025928f538SLaxman Dewangan 	struct regulator_desc desc;
1035928f538SLaxman Dewangan 	struct regmap *regmap;
1045928f538SLaxman Dewangan 	bool enable_external_control;
1055928f538SLaxman Dewangan 	int dvs_gpio;
1065928f538SLaxman Dewangan 	int lru_index[MAX8973_MAX_VOUT_REG];
1075928f538SLaxman Dewangan 	int curr_vout_val[MAX8973_MAX_VOUT_REG];
1085928f538SLaxman Dewangan 	int curr_vout_reg;
1095928f538SLaxman Dewangan 	int curr_gpio_val;
110db892ff6SGuennadi Liakhovetski 	struct regulator_ops ops;
1110f7d6eceSLaxman Dewangan 	enum device_id id;
112d2d5437bSLaxman Dewangan 	int junction_temp_warning;
113d2d5437bSLaxman Dewangan 	int irq;
114d2d5437bSLaxman Dewangan 	struct thermal_zone_device *tz_device;
1155928f538SLaxman Dewangan };
1165928f538SLaxman Dewangan 
1175928f538SLaxman Dewangan /*
1185928f538SLaxman Dewangan  * find_voltage_set_register: Find new voltage configuration register (VOUT).
1195928f538SLaxman Dewangan  * The finding of the new VOUT register will be based on the LRU mechanism.
1205928f538SLaxman Dewangan  * Each VOUT register will have different voltage configured . This
1215928f538SLaxman Dewangan  * Function will look if any of the VOUT register have requested voltage set
1225928f538SLaxman Dewangan  * or not.
1235928f538SLaxman Dewangan  *     - If it is already there then it will make that register as most
1245928f538SLaxman Dewangan  *       recently used and return as found so that caller need not to set
1255928f538SLaxman Dewangan  *       the VOUT register but need to set the proper gpios to select this
1265928f538SLaxman Dewangan  *       VOUT register.
1275928f538SLaxman Dewangan  *     - If requested voltage is not found then it will use the least
1285928f538SLaxman Dewangan  *       recently mechanism to get new VOUT register for new configuration
1295928f538SLaxman Dewangan  *       and will return not_found so that caller need to set new VOUT
1305928f538SLaxman Dewangan  *       register and then gpios (both).
1315928f538SLaxman Dewangan  */
find_voltage_set_register(struct max8973_chip * tps,int req_vsel,int * vout_reg,int * gpio_val)1325928f538SLaxman Dewangan static bool find_voltage_set_register(struct max8973_chip *tps,
1335928f538SLaxman Dewangan 		int req_vsel, int *vout_reg, int *gpio_val)
1345928f538SLaxman Dewangan {
1355928f538SLaxman Dewangan 	int i;
1365928f538SLaxman Dewangan 	bool found = false;
1375928f538SLaxman Dewangan 	int new_vout_reg = tps->lru_index[MAX8973_MAX_VOUT_REG - 1];
1385928f538SLaxman Dewangan 	int found_index = MAX8973_MAX_VOUT_REG - 1;
1395928f538SLaxman Dewangan 
1405928f538SLaxman Dewangan 	for (i = 0; i < MAX8973_MAX_VOUT_REG; ++i) {
1415928f538SLaxman Dewangan 		if (tps->curr_vout_val[tps->lru_index[i]] == req_vsel) {
1425928f538SLaxman Dewangan 			new_vout_reg = tps->lru_index[i];
1435928f538SLaxman Dewangan 			found_index = i;
1445928f538SLaxman Dewangan 			found = true;
1455928f538SLaxman Dewangan 			goto update_lru_index;
1465928f538SLaxman Dewangan 		}
1475928f538SLaxman Dewangan 	}
1485928f538SLaxman Dewangan 
1495928f538SLaxman Dewangan update_lru_index:
1505928f538SLaxman Dewangan 	for (i = found_index; i > 0; i--)
1515928f538SLaxman Dewangan 		tps->lru_index[i] = tps->lru_index[i - 1];
1525928f538SLaxman Dewangan 
1535928f538SLaxman Dewangan 	tps->lru_index[0] = new_vout_reg;
1545928f538SLaxman Dewangan 	*gpio_val = new_vout_reg;
1555928f538SLaxman Dewangan 	*vout_reg = MAX8973_VOUT + new_vout_reg;
1565928f538SLaxman Dewangan 	return found;
1575928f538SLaxman Dewangan }
1585928f538SLaxman Dewangan 
max8973_dcdc_get_voltage_sel(struct regulator_dev * rdev)1595928f538SLaxman Dewangan static int max8973_dcdc_get_voltage_sel(struct regulator_dev *rdev)
1605928f538SLaxman Dewangan {
1615928f538SLaxman Dewangan 	struct max8973_chip *max = rdev_get_drvdata(rdev);
1625928f538SLaxman Dewangan 	unsigned int data;
1635928f538SLaxman Dewangan 	int ret;
1645928f538SLaxman Dewangan 
1655928f538SLaxman Dewangan 	ret = regmap_read(max->regmap, max->curr_vout_reg, &data);
1665928f538SLaxman Dewangan 	if (ret < 0) {
1675928f538SLaxman Dewangan 		dev_err(max->dev, "register %d read failed, err = %d\n",
1685928f538SLaxman Dewangan 			max->curr_vout_reg, ret);
1695928f538SLaxman Dewangan 		return ret;
1705928f538SLaxman Dewangan 	}
1715928f538SLaxman Dewangan 	return data & MAX8973_VOUT_MASK;
1725928f538SLaxman Dewangan }
1735928f538SLaxman Dewangan 
max8973_dcdc_set_voltage_sel(struct regulator_dev * rdev,unsigned vsel)1745928f538SLaxman Dewangan static int max8973_dcdc_set_voltage_sel(struct regulator_dev *rdev,
1755928f538SLaxman Dewangan 	     unsigned vsel)
1765928f538SLaxman Dewangan {
1775928f538SLaxman Dewangan 	struct max8973_chip *max = rdev_get_drvdata(rdev);
1785928f538SLaxman Dewangan 	int ret;
1795928f538SLaxman Dewangan 	bool found = false;
1805928f538SLaxman Dewangan 	int vout_reg = max->curr_vout_reg;
1815928f538SLaxman Dewangan 	int gpio_val = max->curr_gpio_val;
1825928f538SLaxman Dewangan 
1835928f538SLaxman Dewangan 	/*
1845928f538SLaxman Dewangan 	 * If gpios are available to select the VOUT register then least
1855928f538SLaxman Dewangan 	 * recently used register for new configuration.
1865928f538SLaxman Dewangan 	 */
187fa5f509fSLaxman Dewangan 	if (gpio_is_valid(max->dvs_gpio))
1885928f538SLaxman Dewangan 		found = find_voltage_set_register(max, vsel,
1895928f538SLaxman Dewangan 					&vout_reg, &gpio_val);
1905928f538SLaxman Dewangan 
1915928f538SLaxman Dewangan 	if (!found) {
1925928f538SLaxman Dewangan 		ret = regmap_update_bits(max->regmap, vout_reg,
1935928f538SLaxman Dewangan 					MAX8973_VOUT_MASK, vsel);
1945928f538SLaxman Dewangan 		if (ret < 0) {
1955928f538SLaxman Dewangan 			dev_err(max->dev, "register %d update failed, err %d\n",
1965928f538SLaxman Dewangan 				 vout_reg, ret);
1975928f538SLaxman Dewangan 			return ret;
1985928f538SLaxman Dewangan 		}
1995928f538SLaxman Dewangan 		max->curr_vout_reg = vout_reg;
2005928f538SLaxman Dewangan 		max->curr_vout_val[gpio_val] = vsel;
2015928f538SLaxman Dewangan 	}
2025928f538SLaxman Dewangan 
2035928f538SLaxman Dewangan 	/* Select proper VOUT register vio gpios */
204fa5f509fSLaxman Dewangan 	if (gpio_is_valid(max->dvs_gpio)) {
2055928f538SLaxman Dewangan 		gpio_set_value_cansleep(max->dvs_gpio, gpio_val & 0x1);
2065928f538SLaxman Dewangan 		max->curr_gpio_val = gpio_val;
2075928f538SLaxman Dewangan 	}
2085928f538SLaxman Dewangan 	return 0;
2095928f538SLaxman Dewangan }
2105928f538SLaxman Dewangan 
max8973_dcdc_set_mode(struct regulator_dev * rdev,unsigned int mode)2115928f538SLaxman Dewangan static int max8973_dcdc_set_mode(struct regulator_dev *rdev, unsigned int mode)
2125928f538SLaxman Dewangan {
2135928f538SLaxman Dewangan 	struct max8973_chip *max = rdev_get_drvdata(rdev);
2145928f538SLaxman Dewangan 	int ret;
2155928f538SLaxman Dewangan 	int pwm;
2165928f538SLaxman Dewangan 
2175928f538SLaxman Dewangan 	/* Enable force PWM mode in FAST mode only. */
2185928f538SLaxman Dewangan 	switch (mode) {
2195928f538SLaxman Dewangan 	case REGULATOR_MODE_FAST:
2205928f538SLaxman Dewangan 		pwm = MAX8973_FPWM_EN_M;
2215928f538SLaxman Dewangan 		break;
2225928f538SLaxman Dewangan 
2235928f538SLaxman Dewangan 	case REGULATOR_MODE_NORMAL:
2245928f538SLaxman Dewangan 		pwm = 0;
2255928f538SLaxman Dewangan 		break;
2265928f538SLaxman Dewangan 
2275928f538SLaxman Dewangan 	default:
2285928f538SLaxman Dewangan 		return -EINVAL;
2295928f538SLaxman Dewangan 	}
2305928f538SLaxman Dewangan 
2315928f538SLaxman Dewangan 	ret = regmap_update_bits(max->regmap, MAX8973_CONTROL1,
2325928f538SLaxman Dewangan 				MAX8973_FPWM_EN_M, pwm);
2335928f538SLaxman Dewangan 	if (ret < 0)
2345928f538SLaxman Dewangan 		dev_err(max->dev, "register %d update failed, err %d\n",
2355928f538SLaxman Dewangan 				MAX8973_CONTROL1, ret);
2365928f538SLaxman Dewangan 	return ret;
2375928f538SLaxman Dewangan }
2385928f538SLaxman Dewangan 
max8973_dcdc_get_mode(struct regulator_dev * rdev)2395928f538SLaxman Dewangan static unsigned int max8973_dcdc_get_mode(struct regulator_dev *rdev)
2405928f538SLaxman Dewangan {
2415928f538SLaxman Dewangan 	struct max8973_chip *max = rdev_get_drvdata(rdev);
2425928f538SLaxman Dewangan 	unsigned int data;
2435928f538SLaxman Dewangan 	int ret;
2445928f538SLaxman Dewangan 
2455928f538SLaxman Dewangan 	ret = regmap_read(max->regmap, MAX8973_CONTROL1, &data);
2465928f538SLaxman Dewangan 	if (ret < 0) {
2475928f538SLaxman Dewangan 		dev_err(max->dev, "register %d read failed, err %d\n",
2485928f538SLaxman Dewangan 				MAX8973_CONTROL1, ret);
2495928f538SLaxman Dewangan 		return ret;
2505928f538SLaxman Dewangan 	}
2515928f538SLaxman Dewangan 	return (data & MAX8973_FPWM_EN_M) ?
2525928f538SLaxman Dewangan 		REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
2535928f538SLaxman Dewangan }
2545928f538SLaxman Dewangan 
max8973_set_current_limit(struct regulator_dev * rdev,int min_ua,int max_ua)255ffaab991SLaxman Dewangan static int max8973_set_current_limit(struct regulator_dev *rdev,
256ffaab991SLaxman Dewangan 		int min_ua, int max_ua)
257ffaab991SLaxman Dewangan {
258ffaab991SLaxman Dewangan 	struct max8973_chip *max = rdev_get_drvdata(rdev);
259ffaab991SLaxman Dewangan 	unsigned int val;
260ffaab991SLaxman Dewangan 	int ret;
261ffaab991SLaxman Dewangan 
262ffaab991SLaxman Dewangan 	if (max_ua <= 9000000)
263ffaab991SLaxman Dewangan 		val = MAX8973_CKKADV_TRIP_75mV_PER_US;
264ffaab991SLaxman Dewangan 	else if (max_ua <= 12000000)
265ffaab991SLaxman Dewangan 		val = MAX8973_CKKADV_TRIP_150mV_PER_US;
266ffaab991SLaxman Dewangan 	else
267ffaab991SLaxman Dewangan 		val = MAX8973_CKKADV_TRIP_DISABLE;
268ffaab991SLaxman Dewangan 
269ffaab991SLaxman Dewangan 	ret = regmap_update_bits(max->regmap, MAX8973_CONTROL2,
270ffaab991SLaxman Dewangan 			MAX8973_CKKADV_TRIP_MASK, val);
271ffaab991SLaxman Dewangan 	if (ret < 0) {
272ffaab991SLaxman Dewangan 		dev_err(max->dev, "register %d update failed: %d\n",
273ffaab991SLaxman Dewangan 				MAX8973_CONTROL2, ret);
274ffaab991SLaxman Dewangan 		return ret;
275ffaab991SLaxman Dewangan 	}
276ffaab991SLaxman Dewangan 	return 0;
277ffaab991SLaxman Dewangan }
278ffaab991SLaxman Dewangan 
max8973_get_current_limit(struct regulator_dev * rdev)279ffaab991SLaxman Dewangan static int max8973_get_current_limit(struct regulator_dev *rdev)
280ffaab991SLaxman Dewangan {
281ffaab991SLaxman Dewangan 	struct max8973_chip *max = rdev_get_drvdata(rdev);
282ffaab991SLaxman Dewangan 	unsigned int control2;
283ffaab991SLaxman Dewangan 	int ret;
284ffaab991SLaxman Dewangan 
285ffaab991SLaxman Dewangan 	ret = regmap_read(max->regmap, MAX8973_CONTROL2, &control2);
286ffaab991SLaxman Dewangan 	if (ret < 0) {
287ffaab991SLaxman Dewangan 		dev_err(max->dev, "register %d read failed: %d\n",
288ffaab991SLaxman Dewangan 				MAX8973_CONTROL2, ret);
289ffaab991SLaxman Dewangan 		return ret;
290ffaab991SLaxman Dewangan 	}
291ffaab991SLaxman Dewangan 	switch (control2 & MAX8973_CKKADV_TRIP_MASK) {
292ffaab991SLaxman Dewangan 	case MAX8973_CKKADV_TRIP_DISABLE:
293ffaab991SLaxman Dewangan 		return 15000000;
294ffaab991SLaxman Dewangan 	case MAX8973_CKKADV_TRIP_150mV_PER_US:
295ffaab991SLaxman Dewangan 		return 12000000;
296ffaab991SLaxman Dewangan 	case MAX8973_CKKADV_TRIP_75mV_PER_US:
297ffaab991SLaxman Dewangan 		return 9000000;
298ffaab991SLaxman Dewangan 	default:
299ffaab991SLaxman Dewangan 		break;
300ffaab991SLaxman Dewangan 	}
301ffaab991SLaxman Dewangan 	return 9000000;
302ffaab991SLaxman Dewangan }
303ffaab991SLaxman Dewangan 
3048590ccd4SAxel Lin static const unsigned int max8973_buck_ramp_table[] = {
3058590ccd4SAxel Lin 	12000, 25000, 50000, 200000
3068590ccd4SAxel Lin };
3078590ccd4SAxel Lin 
308db892ff6SGuennadi Liakhovetski static const struct regulator_ops max8973_dcdc_ops = {
3095928f538SLaxman Dewangan 	.get_voltage_sel	= max8973_dcdc_get_voltage_sel,
3105928f538SLaxman Dewangan 	.set_voltage_sel	= max8973_dcdc_set_voltage_sel,
3115928f538SLaxman Dewangan 	.list_voltage		= regulator_list_voltage_linear,
3125928f538SLaxman Dewangan 	.set_mode		= max8973_dcdc_set_mode,
3135928f538SLaxman Dewangan 	.get_mode		= max8973_dcdc_get_mode,
3143064c1f3SLaxman Dewangan 	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
3158590ccd4SAxel Lin 	.set_ramp_delay		= regulator_set_ramp_delay_regmap,
3165928f538SLaxman Dewangan };
3175928f538SLaxman Dewangan 
max8973_init_dcdc(struct max8973_chip * max,struct max8973_regulator_platform_data * pdata)3183d68dfe3SGreg Kroah-Hartman static int max8973_init_dcdc(struct max8973_chip *max,
3195928f538SLaxman Dewangan 			     struct max8973_regulator_platform_data *pdata)
3205928f538SLaxman Dewangan {
3215928f538SLaxman Dewangan 	int ret;
3225928f538SLaxman Dewangan 	uint8_t	control1 = 0;
3235928f538SLaxman Dewangan 	uint8_t control2 = 0;
3243064c1f3SLaxman Dewangan 	unsigned int data;
3253064c1f3SLaxman Dewangan 
3263064c1f3SLaxman Dewangan 	ret = regmap_read(max->regmap, MAX8973_CONTROL1, &data);
3273064c1f3SLaxman Dewangan 	if (ret < 0) {
3283064c1f3SLaxman Dewangan 		dev_err(max->dev, "register %d read failed, err = %d",
3293064c1f3SLaxman Dewangan 				MAX8973_CONTROL1, ret);
3303064c1f3SLaxman Dewangan 		return ret;
3313064c1f3SLaxman Dewangan 	}
3323064c1f3SLaxman Dewangan 	control1 = data & MAX8973_RAMP_MASK;
3333064c1f3SLaxman Dewangan 	switch (control1) {
3343064c1f3SLaxman Dewangan 	case MAX8973_RAMP_12mV_PER_US:
3353064c1f3SLaxman Dewangan 		max->desc.ramp_delay = 12000;
3363064c1f3SLaxman Dewangan 		break;
3373064c1f3SLaxman Dewangan 	case MAX8973_RAMP_25mV_PER_US:
338366604ecSAxel Lin 		max->desc.ramp_delay = 25000;
3393064c1f3SLaxman Dewangan 		break;
3403064c1f3SLaxman Dewangan 	case MAX8973_RAMP_50mV_PER_US:
3413064c1f3SLaxman Dewangan 		max->desc.ramp_delay = 50000;
3423064c1f3SLaxman Dewangan 		break;
3433064c1f3SLaxman Dewangan 	case MAX8973_RAMP_200mV_PER_US:
3443064c1f3SLaxman Dewangan 		max->desc.ramp_delay = 200000;
3453064c1f3SLaxman Dewangan 		break;
3463064c1f3SLaxman Dewangan 	}
3475928f538SLaxman Dewangan 
3485928f538SLaxman Dewangan 	if (pdata->control_flags & MAX8973_CONTROL_REMOTE_SENSE_ENABLE)
3495928f538SLaxman Dewangan 		control1 |= MAX8973_SNS_ENABLE;
3505928f538SLaxman Dewangan 
3515928f538SLaxman Dewangan 	if (!(pdata->control_flags & MAX8973_CONTROL_FALLING_SLEW_RATE_ENABLE))
3525928f538SLaxman Dewangan 		control1 |= MAX8973_NFSR_ENABLE;
3535928f538SLaxman Dewangan 
3545928f538SLaxman Dewangan 	if (pdata->control_flags & MAX8973_CONTROL_OUTPUT_ACTIVE_DISCH_ENABLE)
3555928f538SLaxman Dewangan 		control1 |= MAX8973_AD_ENABLE;
3565928f538SLaxman Dewangan 
357dcd9ec6aSLaxman Dewangan 	if (pdata->control_flags & MAX8973_CONTROL_BIAS_ENABLE) {
3585928f538SLaxman Dewangan 		control1 |= MAX8973_BIAS_ENABLE;
359dcd9ec6aSLaxman Dewangan 		max->desc.enable_time = 20;
360dcd9ec6aSLaxman Dewangan 	} else {
361dcd9ec6aSLaxman Dewangan 		max->desc.enable_time = 240;
362dcd9ec6aSLaxman Dewangan 	}
3635928f538SLaxman Dewangan 
3645928f538SLaxman Dewangan 	if (pdata->control_flags & MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE)
3655928f538SLaxman Dewangan 		control1 |= MAX8973_FREQSHIFT_9PER;
3665928f538SLaxman Dewangan 
367d2d5437bSLaxman Dewangan 	if ((pdata->junction_temp_warning == MAX77621_TJINT_WARNING_TEMP_120) &&
368d2d5437bSLaxman Dewangan 	    (max->id == MAX77621))
369d2d5437bSLaxman Dewangan 		control2 |= MAX77621_T_JUNCTION_120;
370d2d5437bSLaxman Dewangan 
3715928f538SLaxman Dewangan 	if (!(pdata->control_flags & MAX8973_CONTROL_PULL_DOWN_ENABLE))
3725928f538SLaxman Dewangan 		control2 |= MAX8973_DISCH_ENBABLE;
3735928f538SLaxman Dewangan 
3745928f538SLaxman Dewangan 	/*  Clock advance trip configuration */
3755928f538SLaxman Dewangan 	switch (pdata->control_flags & MAX8973_CONTROL_CLKADV_TRIP_MASK) {
3765928f538SLaxman Dewangan 	case MAX8973_CONTROL_CLKADV_TRIP_DISABLED:
3775928f538SLaxman Dewangan 		control2 |= MAX8973_CKKADV_TRIP_DISABLE;
3785928f538SLaxman Dewangan 		break;
3795928f538SLaxman Dewangan 
3805928f538SLaxman Dewangan 	case MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US:
3815928f538SLaxman Dewangan 		control2 |= MAX8973_CKKADV_TRIP_75mV_PER_US;
3825928f538SLaxman Dewangan 		break;
3835928f538SLaxman Dewangan 
3845928f538SLaxman Dewangan 	case MAX8973_CONTROL_CLKADV_TRIP_150mV_PER_US:
3855928f538SLaxman Dewangan 		control2 |= MAX8973_CKKADV_TRIP_150mV_PER_US;
3865928f538SLaxman Dewangan 		break;
3875928f538SLaxman Dewangan 
3885928f538SLaxman Dewangan 	case MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US_HIST_DIS:
3895928f538SLaxman Dewangan 		control2 |= MAX8973_CKKADV_TRIP_75mV_PER_US_HIST_DIS;
3905928f538SLaxman Dewangan 		break;
3915928f538SLaxman Dewangan 	}
3925928f538SLaxman Dewangan 
3935928f538SLaxman Dewangan 	/* Configure inductor value */
3945928f538SLaxman Dewangan 	switch (pdata->control_flags & MAX8973_CONTROL_INDUCTOR_VALUE_MASK) {
3955928f538SLaxman Dewangan 	case MAX8973_CONTROL_INDUCTOR_VALUE_NOMINAL:
3965928f538SLaxman Dewangan 		control2 |= MAX8973_INDUCTOR_NOMINAL;
3975928f538SLaxman Dewangan 		break;
3985928f538SLaxman Dewangan 
3995928f538SLaxman Dewangan 	case MAX8973_CONTROL_INDUCTOR_VALUE_MINUS_30_PER:
4005928f538SLaxman Dewangan 		control2 |= MAX8973_INDUCTOR_MIN_30_PER;
4015928f538SLaxman Dewangan 		break;
4025928f538SLaxman Dewangan 
4035928f538SLaxman Dewangan 	case MAX8973_CONTROL_INDUCTOR_VALUE_PLUS_30_PER:
4045928f538SLaxman Dewangan 		control2 |= MAX8973_INDUCTOR_PLUS_30_PER;
4055928f538SLaxman Dewangan 		break;
4065928f538SLaxman Dewangan 
4075928f538SLaxman Dewangan 	case MAX8973_CONTROL_INDUCTOR_VALUE_PLUS_60_PER:
4085928f538SLaxman Dewangan 		control2 |= MAX8973_INDUCTOR_PLUS_60_PER;
4095928f538SLaxman Dewangan 		break;
4105928f538SLaxman Dewangan 	}
4115928f538SLaxman Dewangan 
4125928f538SLaxman Dewangan 	ret = regmap_write(max->regmap, MAX8973_CONTROL1, control1);
4135928f538SLaxman Dewangan 	if (ret < 0) {
4145928f538SLaxman Dewangan 		dev_err(max->dev, "register %d write failed, err = %d",
4155928f538SLaxman Dewangan 				MAX8973_CONTROL1, ret);
4165928f538SLaxman Dewangan 		return ret;
4175928f538SLaxman Dewangan 	}
4185928f538SLaxman Dewangan 
4195928f538SLaxman Dewangan 	ret = regmap_write(max->regmap, MAX8973_CONTROL2, control2);
4205928f538SLaxman Dewangan 	if (ret < 0) {
4215928f538SLaxman Dewangan 		dev_err(max->dev, "register %d write failed, err = %d",
4225928f538SLaxman Dewangan 				MAX8973_CONTROL2, ret);
4235928f538SLaxman Dewangan 		return ret;
4245928f538SLaxman Dewangan 	}
4255928f538SLaxman Dewangan 
4265928f538SLaxman Dewangan 	/* If external control is enabled then disable EN bit */
4270f7d6eceSLaxman Dewangan 	if (max->enable_external_control && (max->id == MAX8973)) {
4285928f538SLaxman Dewangan 		ret = regmap_update_bits(max->regmap, MAX8973_VOUT,
4295928f538SLaxman Dewangan 						MAX8973_VOUT_ENABLE, 0);
4305928f538SLaxman Dewangan 		if (ret < 0)
4315928f538SLaxman Dewangan 			dev_err(max->dev, "register %d update failed, err = %d",
4325928f538SLaxman Dewangan 				MAX8973_VOUT, ret);
4335928f538SLaxman Dewangan 	}
4345928f538SLaxman Dewangan 	return ret;
4355928f538SLaxman Dewangan }
4365928f538SLaxman Dewangan 
max8973_thermal_read_temp(struct thermal_zone_device * tz,int * temp)437826855ffSDaniel Lezcano static int max8973_thermal_read_temp(struct thermal_zone_device *tz, int *temp)
438d2d5437bSLaxman Dewangan {
4393d4e1badSDaniel Lezcano 	struct max8973_chip *mchip = thermal_zone_device_priv(tz);
440d2d5437bSLaxman Dewangan 	unsigned int val;
441d2d5437bSLaxman Dewangan 	int ret;
442d2d5437bSLaxman Dewangan 
443d2d5437bSLaxman Dewangan 	ret = regmap_read(mchip->regmap, MAX8973_CHIPID1, &val);
444d2d5437bSLaxman Dewangan 	if (ret < 0) {
445d2d5437bSLaxman Dewangan 		dev_err(mchip->dev, "Failed to read register CHIPID1, %d", ret);
446d2d5437bSLaxman Dewangan 		return ret;
447d2d5437bSLaxman Dewangan 	}
448d2d5437bSLaxman Dewangan 
449bbc7ba0fSTom Rix 	/* +1 degC to trigger cool device */
450d2d5437bSLaxman Dewangan 	if (val & MAX77621_CHIPID_TJINT_S)
451d2d5437bSLaxman Dewangan 		*temp = mchip->junction_temp_warning + 1000;
452d2d5437bSLaxman Dewangan 	else
453d2d5437bSLaxman Dewangan 		*temp = MAX77621_NORMAL_OPERATING_TEMP;
454d2d5437bSLaxman Dewangan 
455d2d5437bSLaxman Dewangan 	return 0;
456d2d5437bSLaxman Dewangan }
457d2d5437bSLaxman Dewangan 
max8973_thermal_irq(int irq,void * data)458d2d5437bSLaxman Dewangan static irqreturn_t max8973_thermal_irq(int irq, void *data)
459d2d5437bSLaxman Dewangan {
460d2d5437bSLaxman Dewangan 	struct max8973_chip *mchip = data;
461d2d5437bSLaxman Dewangan 
4620e70f466SSrinivas Pandruvada 	thermal_zone_device_update(mchip->tz_device,
4630e70f466SSrinivas Pandruvada 				   THERMAL_EVENT_UNSPECIFIED);
464d2d5437bSLaxman Dewangan 
465d2d5437bSLaxman Dewangan 	return IRQ_HANDLED;
466d2d5437bSLaxman Dewangan }
467d2d5437bSLaxman Dewangan 
468826855ffSDaniel Lezcano static const struct thermal_zone_device_ops max77621_tz_ops = {
469d2d5437bSLaxman Dewangan 	.get_temp = max8973_thermal_read_temp,
470d2d5437bSLaxman Dewangan };
471d2d5437bSLaxman Dewangan 
max8973_thermal_init(struct max8973_chip * mchip)472d2d5437bSLaxman Dewangan static int max8973_thermal_init(struct max8973_chip *mchip)
473d2d5437bSLaxman Dewangan {
474d2d5437bSLaxman Dewangan 	struct thermal_zone_device *tzd;
475d2d5437bSLaxman Dewangan 	struct irq_data *irq_data;
476d2d5437bSLaxman Dewangan 	unsigned long irq_flags = 0;
477d2d5437bSLaxman Dewangan 	int ret;
478d2d5437bSLaxman Dewangan 
479d2d5437bSLaxman Dewangan 	if (mchip->id != MAX77621)
480d2d5437bSLaxman Dewangan 		return 0;
481d2d5437bSLaxman Dewangan 
482826855ffSDaniel Lezcano 	tzd = devm_thermal_of_zone_register(mchip->dev, 0, mchip,
483d2d5437bSLaxman Dewangan 					    &max77621_tz_ops);
484d2d5437bSLaxman Dewangan 	if (IS_ERR(tzd)) {
485d2d5437bSLaxman Dewangan 		ret = PTR_ERR(tzd);
486d2d5437bSLaxman Dewangan 		dev_err(mchip->dev, "Failed to register thermal sensor: %d\n",
487d2d5437bSLaxman Dewangan 			ret);
488d2d5437bSLaxman Dewangan 		return ret;
489d2d5437bSLaxman Dewangan 	}
490d2d5437bSLaxman Dewangan 
491d2d5437bSLaxman Dewangan 	if (mchip->irq <= 0)
492d2d5437bSLaxman Dewangan 		return 0;
493d2d5437bSLaxman Dewangan 
494d2d5437bSLaxman Dewangan 	irq_data = irq_get_irq_data(mchip->irq);
495d2d5437bSLaxman Dewangan 	if (irq_data)
496d2d5437bSLaxman Dewangan 		irq_flags = irqd_get_trigger_type(irq_data);
497d2d5437bSLaxman Dewangan 
498d2d5437bSLaxman Dewangan 	ret = devm_request_threaded_irq(mchip->dev, mchip->irq, NULL,
499d2d5437bSLaxman Dewangan 					max8973_thermal_irq,
500d2d5437bSLaxman Dewangan 					IRQF_ONESHOT | IRQF_SHARED | irq_flags,
501d2d5437bSLaxman Dewangan 					dev_name(mchip->dev), mchip);
502d2d5437bSLaxman Dewangan 	if (ret < 0) {
503d2d5437bSLaxman Dewangan 		dev_err(mchip->dev, "Failed to request irq %d, %d\n",
504d2d5437bSLaxman Dewangan 			mchip->irq, ret);
505d2d5437bSLaxman Dewangan 		return ret;
506d2d5437bSLaxman Dewangan 	}
507d2d5437bSLaxman Dewangan 
508d2d5437bSLaxman Dewangan 	return 0;
509d2d5437bSLaxman Dewangan }
510d2d5437bSLaxman Dewangan 
5115928f538SLaxman Dewangan static const struct regmap_config max8973_regmap_config = {
5125928f538SLaxman Dewangan 	.reg_bits		= 8,
5135928f538SLaxman Dewangan 	.val_bits		= 8,
5145928f538SLaxman Dewangan 	.max_register		= MAX8973_CHIPID2,
5155928f538SLaxman Dewangan 	.cache_type		= REGCACHE_RBTREE,
5165928f538SLaxman Dewangan };
5175928f538SLaxman Dewangan 
max8973_parse_dt(struct device * dev)518c2ffa973SLaxman Dewangan static struct max8973_regulator_platform_data *max8973_parse_dt(
519c2ffa973SLaxman Dewangan 		struct device *dev)
520c2ffa973SLaxman Dewangan {
521c2ffa973SLaxman Dewangan 	struct max8973_regulator_platform_data *pdata;
522c2ffa973SLaxman Dewangan 	struct device_node *np = dev->of_node;
523c2ffa973SLaxman Dewangan 	int ret;
524c2ffa973SLaxman Dewangan 	u32 pval;
5253692db3aSLaxman Dewangan 	bool etr_enable;
5263692db3aSLaxman Dewangan 	bool etr_sensitivity_high;
527c2ffa973SLaxman Dewangan 
528c2ffa973SLaxman Dewangan 	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
529c2ffa973SLaxman Dewangan 	if (!pdata)
530c2ffa973SLaxman Dewangan 		return NULL;
531c2ffa973SLaxman Dewangan 
532c2ffa973SLaxman Dewangan 	pdata->enable_ext_control = of_property_read_bool(np,
533c2ffa973SLaxman Dewangan 						"maxim,externally-enable");
534c2ffa973SLaxman Dewangan 	pdata->dvs_gpio = of_get_named_gpio(np, "maxim,dvs-gpio", 0);
535c2ffa973SLaxman Dewangan 
536c2ffa973SLaxman Dewangan 	ret = of_property_read_u32(np, "maxim,dvs-default-state", &pval);
537c2ffa973SLaxman Dewangan 	if (!ret)
538c2ffa973SLaxman Dewangan 		pdata->dvs_def_state = pval;
539c2ffa973SLaxman Dewangan 
540c2ffa973SLaxman Dewangan 	if (of_property_read_bool(np, "maxim,enable-remote-sense"))
541c2ffa973SLaxman Dewangan 		pdata->control_flags  |= MAX8973_CONTROL_REMOTE_SENSE_ENABLE;
542c2ffa973SLaxman Dewangan 
543c2ffa973SLaxman Dewangan 	if (of_property_read_bool(np, "maxim,enable-falling-slew-rate"))
544c2ffa973SLaxman Dewangan 		pdata->control_flags  |=
545c2ffa973SLaxman Dewangan 				MAX8973_CONTROL_FALLING_SLEW_RATE_ENABLE;
546c2ffa973SLaxman Dewangan 
547c2ffa973SLaxman Dewangan 	if (of_property_read_bool(np, "maxim,enable-active-discharge"))
548c2ffa973SLaxman Dewangan 		pdata->control_flags  |=
549c2ffa973SLaxman Dewangan 				MAX8973_CONTROL_OUTPUT_ACTIVE_DISCH_ENABLE;
550c2ffa973SLaxman Dewangan 
551c2ffa973SLaxman Dewangan 	if (of_property_read_bool(np, "maxim,enable-frequency-shift"))
552c2ffa973SLaxman Dewangan 		pdata->control_flags  |= MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE;
553c2ffa973SLaxman Dewangan 
554c2ffa973SLaxman Dewangan 	if (of_property_read_bool(np, "maxim,enable-bias-control"))
555127e1062SLaxman Dewangan 		pdata->control_flags  |= MAX8973_CONTROL_BIAS_ENABLE;
556c2ffa973SLaxman Dewangan 
5573692db3aSLaxman Dewangan 	etr_enable = of_property_read_bool(np, "maxim,enable-etr");
5583692db3aSLaxman Dewangan 	etr_sensitivity_high = of_property_read_bool(np,
5593692db3aSLaxman Dewangan 				"maxim,enable-high-etr-sensitivity");
5603692db3aSLaxman Dewangan 	if (etr_sensitivity_high)
5613692db3aSLaxman Dewangan 		etr_enable = true;
5623692db3aSLaxman Dewangan 
5633692db3aSLaxman Dewangan 	if (etr_enable) {
5643692db3aSLaxman Dewangan 		if (etr_sensitivity_high)
5653692db3aSLaxman Dewangan 			pdata->control_flags |=
5663692db3aSLaxman Dewangan 				MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US;
5673692db3aSLaxman Dewangan 		else
5683692db3aSLaxman Dewangan 			pdata->control_flags |=
5693692db3aSLaxman Dewangan 				MAX8973_CONTROL_CLKADV_TRIP_150mV_PER_US;
5703692db3aSLaxman Dewangan 	} else {
5713692db3aSLaxman Dewangan 		pdata->control_flags |= MAX8973_CONTROL_CLKADV_TRIP_DISABLED;
5723692db3aSLaxman Dewangan 	}
5733692db3aSLaxman Dewangan 
574d2d5437bSLaxman Dewangan 	pdata->junction_temp_warning = MAX77621_TJINT_WARNING_TEMP_140;
575d2d5437bSLaxman Dewangan 	ret = of_property_read_u32(np, "junction-warn-millicelsius", &pval);
576d2d5437bSLaxman Dewangan 	if (!ret && (pval <= MAX77621_TJINT_WARNING_TEMP_120))
577d2d5437bSLaxman Dewangan 		pdata->junction_temp_warning = MAX77621_TJINT_WARNING_TEMP_120;
578d2d5437bSLaxman Dewangan 
579c2ffa973SLaxman Dewangan 	return pdata;
580c2ffa973SLaxman Dewangan }
581c2ffa973SLaxman Dewangan 
5820f7d6eceSLaxman Dewangan static const struct of_device_id of_max8973_match_tbl[] = {
5830f7d6eceSLaxman Dewangan 	{ .compatible = "maxim,max8973", .data = (void *)MAX8973, },
5840f7d6eceSLaxman Dewangan 	{ .compatible = "maxim,max77621", .data = (void *)MAX77621, },
5850f7d6eceSLaxman Dewangan 	{ },
5860f7d6eceSLaxman Dewangan };
5870f7d6eceSLaxman Dewangan MODULE_DEVICE_TABLE(of, of_max8973_match_tbl);
5880f7d6eceSLaxman Dewangan 
max8973_probe(struct i2c_client * client)5894e85e5d6SUwe Kleine-König static int max8973_probe(struct i2c_client *client)
5905928f538SLaxman Dewangan {
5914e85e5d6SUwe Kleine-König 	const struct i2c_device_id *id = i2c_client_get_device_id(client);
5925928f538SLaxman Dewangan 	struct max8973_regulator_platform_data *pdata;
59369eb0980SLaxman Dewangan 	struct regulator_init_data *ridata;
5945928f538SLaxman Dewangan 	struct regulator_config config = { };
5955928f538SLaxman Dewangan 	struct regulator_dev *rdev;
5965928f538SLaxman Dewangan 	struct max8973_chip *max;
597c2ffa973SLaxman Dewangan 	bool pdata_from_dt = false;
5980f7d6eceSLaxman Dewangan 	unsigned int chip_id;
599e7d2be69SLinus Walleij 	struct gpio_desc *gpiod;
600e7d2be69SLinus Walleij 	enum gpiod_flags gflags;
6015928f538SLaxman Dewangan 	int ret;
6025928f538SLaxman Dewangan 
603dff91d0bSJingoo Han 	pdata = dev_get_platdata(&client->dev);
60442dc3023SGuennadi Liakhovetski 
605c2ffa973SLaxman Dewangan 	if (!pdata && client->dev.of_node) {
606c2ffa973SLaxman Dewangan 		pdata = max8973_parse_dt(&client->dev);
607c2ffa973SLaxman Dewangan 		pdata_from_dt = true;
608c2ffa973SLaxman Dewangan 	}
609c2ffa973SLaxman Dewangan 
610c2ffa973SLaxman Dewangan 	if (!pdata) {
6115928f538SLaxman Dewangan 		dev_err(&client->dev, "No Platform data");
6125928f538SLaxman Dewangan 		return -EIO;
6135928f538SLaxman Dewangan 	}
6145928f538SLaxman Dewangan 
615e7d2be69SLinus Walleij 	if (pdata->dvs_gpio == -EPROBE_DEFER)
616c2ffa973SLaxman Dewangan 		return -EPROBE_DEFER;
617c2ffa973SLaxman Dewangan 
6185928f538SLaxman Dewangan 	max = devm_kzalloc(&client->dev, sizeof(*max), GFP_KERNEL);
61921024deeSSachin Kamat 	if (!max)
6205928f538SLaxman Dewangan 		return -ENOMEM;
6215928f538SLaxman Dewangan 
6225928f538SLaxman Dewangan 	max->regmap = devm_regmap_init_i2c(client, &max8973_regmap_config);
6235928f538SLaxman Dewangan 	if (IS_ERR(max->regmap)) {
6245928f538SLaxman Dewangan 		ret = PTR_ERR(max->regmap);
6255928f538SLaxman Dewangan 		dev_err(&client->dev, "regmap init failed, err %d\n", ret);
6265928f538SLaxman Dewangan 		return ret;
6275928f538SLaxman Dewangan 	}
6285928f538SLaxman Dewangan 
6290f7d6eceSLaxman Dewangan 	if (client->dev.of_node) {
6300f7d6eceSLaxman Dewangan 		const struct of_device_id *match;
6310f7d6eceSLaxman Dewangan 
6320f7d6eceSLaxman Dewangan 		match = of_match_device(of_match_ptr(of_max8973_match_tbl),
6330f7d6eceSLaxman Dewangan 				&client->dev);
6340f7d6eceSLaxman Dewangan 		if (!match)
6350f7d6eceSLaxman Dewangan 			return -ENODATA;
6360f7d6eceSLaxman Dewangan 		max->id = (u32)((uintptr_t)match->data);
6370f7d6eceSLaxman Dewangan 	} else {
6380f7d6eceSLaxman Dewangan 		max->id = id->driver_data;
6390f7d6eceSLaxman Dewangan 	}
6400f7d6eceSLaxman Dewangan 
6410f7d6eceSLaxman Dewangan 	ret = regmap_read(max->regmap, MAX8973_CHIPID1, &chip_id);
6420f7d6eceSLaxman Dewangan 	if (ret < 0) {
6430f7d6eceSLaxman Dewangan 		dev_err(&client->dev, "register CHIPID1 read failed, %d", ret);
6440f7d6eceSLaxman Dewangan 		return ret;
6450f7d6eceSLaxman Dewangan 	}
6460f7d6eceSLaxman Dewangan 
6470f7d6eceSLaxman Dewangan 	dev_info(&client->dev, "CHIP-ID OTP: 0x%02x ID_M: 0x%02x\n",
6480f7d6eceSLaxman Dewangan 			(chip_id >> 4) & 0xF, (chip_id >> 1) & 0x7);
6490f7d6eceSLaxman Dewangan 
6505928f538SLaxman Dewangan 	i2c_set_clientdata(client, max);
651db892ff6SGuennadi Liakhovetski 	max->ops = max8973_dcdc_ops;
6525928f538SLaxman Dewangan 	max->dev = &client->dev;
6535928f538SLaxman Dewangan 	max->desc.name = id->name;
6545928f538SLaxman Dewangan 	max->desc.id = 0;
655db892ff6SGuennadi Liakhovetski 	max->desc.ops = &max->ops;
6565928f538SLaxman Dewangan 	max->desc.type = REGULATOR_VOLTAGE;
6575928f538SLaxman Dewangan 	max->desc.owner = THIS_MODULE;
6585928f538SLaxman Dewangan 	max->desc.min_uV = MAX8973_MIN_VOLATGE;
6595928f538SLaxman Dewangan 	max->desc.uV_step = MAX8973_VOLATGE_STEP;
6605928f538SLaxman Dewangan 	max->desc.n_voltages = MAX8973_BUCK_N_VOLTAGE;
6618590ccd4SAxel Lin 	max->desc.ramp_reg = MAX8973_CONTROL1;
6628590ccd4SAxel Lin 	max->desc.ramp_mask = MAX8973_RAMP_MASK;
6638590ccd4SAxel Lin 	max->desc.ramp_delay_table = max8973_buck_ramp_table;
6648590ccd4SAxel Lin 	max->desc.n_ramp_values = ARRAY_SIZE(max8973_buck_ramp_table);
6655928f538SLaxman Dewangan 
66669eb0980SLaxman Dewangan 	max->dvs_gpio = (pdata->dvs_gpio) ? pdata->dvs_gpio : -EINVAL;
66769eb0980SLaxman Dewangan 	max->enable_external_control = pdata->enable_ext_control;
66869eb0980SLaxman Dewangan 	max->curr_gpio_val = pdata->dvs_def_state;
66969eb0980SLaxman Dewangan 	max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state;
670d2d5437bSLaxman Dewangan 	max->junction_temp_warning = pdata->junction_temp_warning;
67169eb0980SLaxman Dewangan 
6725928f538SLaxman Dewangan 	max->lru_index[0] = max->curr_vout_reg;
6735928f538SLaxman Dewangan 
6745928f538SLaxman Dewangan 	if (gpio_is_valid(max->dvs_gpio)) {
6755928f538SLaxman Dewangan 		int gpio_flags;
6765928f538SLaxman Dewangan 		int i;
6775928f538SLaxman Dewangan 
6785928f538SLaxman Dewangan 		gpio_flags = (pdata->dvs_def_state) ?
6795928f538SLaxman Dewangan 				GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
6805928f538SLaxman Dewangan 		ret = devm_gpio_request_one(&client->dev, max->dvs_gpio,
6815928f538SLaxman Dewangan 				gpio_flags, "max8973-dvs");
6825928f538SLaxman Dewangan 		if (ret) {
6835928f538SLaxman Dewangan 			dev_err(&client->dev,
6845928f538SLaxman Dewangan 				"gpio_request for gpio %d failed, err = %d\n",
6855928f538SLaxman Dewangan 				max->dvs_gpio, ret);
6865928f538SLaxman Dewangan 			return ret;
6875928f538SLaxman Dewangan 		}
6885928f538SLaxman Dewangan 
6895928f538SLaxman Dewangan 		/*
6905928f538SLaxman Dewangan 		 * Initialize the lru index with vout_reg id
6915928f538SLaxman Dewangan 		 * The index 0 will be most recently used and
6925928f538SLaxman Dewangan 		 * set with the max->curr_vout_reg */
6935928f538SLaxman Dewangan 		for (i = 0; i < MAX8973_MAX_VOUT_REG; ++i)
6945928f538SLaxman Dewangan 			max->lru_index[i] = i;
6955928f538SLaxman Dewangan 		max->lru_index[0] = max->curr_vout_reg;
6965928f538SLaxman Dewangan 		max->lru_index[max->curr_vout_reg] = 0;
697b10c7f3cSMikko Perttunen 	} else {
698b10c7f3cSMikko Perttunen 		/*
699b10c7f3cSMikko Perttunen 		 * If there is no DVS GPIO, the VOUT register
700b10c7f3cSMikko Perttunen 		 * address is fixed.
701b10c7f3cSMikko Perttunen 		 */
702b10c7f3cSMikko Perttunen 		max->ops.set_voltage_sel = regulator_set_voltage_sel_regmap;
703b10c7f3cSMikko Perttunen 		max->ops.get_voltage_sel = regulator_get_voltage_sel_regmap;
704b10c7f3cSMikko Perttunen 		max->desc.vsel_reg = max->curr_vout_reg;
705b10c7f3cSMikko Perttunen 		max->desc.vsel_mask = MAX8973_VOUT_MASK;
7065928f538SLaxman Dewangan 	}
7075928f538SLaxman Dewangan 
708c2ffa973SLaxman Dewangan 	if (pdata_from_dt)
709c2ffa973SLaxman Dewangan 		pdata->reg_init_data = of_get_regulator_init_data(&client->dev,
710c2ffa973SLaxman Dewangan 					client->dev.of_node, &max->desc);
711c2ffa973SLaxman Dewangan 
7120f7d6eceSLaxman Dewangan 	ridata = pdata->reg_init_data;
7130f7d6eceSLaxman Dewangan 	switch (max->id) {
7140f7d6eceSLaxman Dewangan 	case MAX8973:
7150f7d6eceSLaxman Dewangan 		if (!pdata->enable_ext_control) {
7160f7d6eceSLaxman Dewangan 			max->desc.enable_reg = MAX8973_VOUT;
7170f7d6eceSLaxman Dewangan 			max->desc.enable_mask = MAX8973_VOUT_ENABLE;
7180f7d6eceSLaxman Dewangan 			max->ops.enable = regulator_enable_regmap;
7190f7d6eceSLaxman Dewangan 			max->ops.disable = regulator_disable_regmap;
7200f7d6eceSLaxman Dewangan 			max->ops.is_enabled = regulator_is_enabled_regmap;
7210f7d6eceSLaxman Dewangan 			break;
7220f7d6eceSLaxman Dewangan 		}
7230f7d6eceSLaxman Dewangan 
7240f7d6eceSLaxman Dewangan 		if (ridata && (ridata->constraints.always_on ||
7250f7d6eceSLaxman Dewangan 			       ridata->constraints.boot_on))
726e7d2be69SLinus Walleij 			gflags = GPIOD_OUT_HIGH;
727e7d2be69SLinus Walleij 		else
728e7d2be69SLinus Walleij 			gflags = GPIOD_OUT_LOW;
72963239e4bSLinus Walleij 		gflags |= GPIOD_FLAGS_BIT_NONEXCLUSIVE;
730e7d2be69SLinus Walleij 		gpiod = devm_gpiod_get_optional(&client->dev,
731e7d2be69SLinus Walleij 						"maxim,enable",
732e7d2be69SLinus Walleij 						gflags);
733e7d2be69SLinus Walleij 		if (IS_ERR(gpiod))
734e7d2be69SLinus Walleij 			return PTR_ERR(gpiod);
735e7d2be69SLinus Walleij 		if (gpiod) {
736e7d2be69SLinus Walleij 			config.ena_gpiod = gpiod;
737e7d2be69SLinus Walleij 			max->enable_external_control = true;
7380f7d6eceSLaxman Dewangan 		}
739e7d2be69SLinus Walleij 
7400f7d6eceSLaxman Dewangan 		break;
7410f7d6eceSLaxman Dewangan 
7420f7d6eceSLaxman Dewangan 	case MAX77621:
743e7d2be69SLinus Walleij 		/*
744e7d2be69SLinus Walleij 		 * We do not let the core switch this regulator on/off,
745e7d2be69SLinus Walleij 		 * we just leave it on.
746e7d2be69SLinus Walleij 		 */
747e7d2be69SLinus Walleij 		gpiod = devm_gpiod_get_optional(&client->dev,
748e7d2be69SLinus Walleij 						"maxim,enable",
749e7d2be69SLinus Walleij 						GPIOD_OUT_HIGH);
750e7d2be69SLinus Walleij 		if (IS_ERR(gpiod))
751e7d2be69SLinus Walleij 			return PTR_ERR(gpiod);
752e7d2be69SLinus Walleij 		if (gpiod)
753e7d2be69SLinus Walleij 			max->enable_external_control = true;
7540f7d6eceSLaxman Dewangan 
7550f7d6eceSLaxman Dewangan 		max->desc.enable_reg = MAX8973_VOUT;
7560f7d6eceSLaxman Dewangan 		max->desc.enable_mask = MAX8973_VOUT_ENABLE;
7570f7d6eceSLaxman Dewangan 		max->ops.enable = regulator_enable_regmap;
7580f7d6eceSLaxman Dewangan 		max->ops.disable = regulator_disable_regmap;
7590f7d6eceSLaxman Dewangan 		max->ops.is_enabled = regulator_is_enabled_regmap;
760ffaab991SLaxman Dewangan 		max->ops.set_current_limit = max8973_set_current_limit;
761ffaab991SLaxman Dewangan 		max->ops.get_current_limit = max8973_get_current_limit;
7620f7d6eceSLaxman Dewangan 		break;
7630f7d6eceSLaxman Dewangan 	default:
7640f7d6eceSLaxman Dewangan 		break;
7650f7d6eceSLaxman Dewangan 	}
7660f7d6eceSLaxman Dewangan 
7675928f538SLaxman Dewangan 	ret = max8973_init_dcdc(max, pdata);
7685928f538SLaxman Dewangan 	if (ret < 0) {
7695928f538SLaxman Dewangan 		dev_err(max->dev, "Max8973 Init failed, err = %d\n", ret);
7705928f538SLaxman Dewangan 		return ret;
7715928f538SLaxman Dewangan 	}
7725928f538SLaxman Dewangan 
7735928f538SLaxman Dewangan 	config.dev = &client->dev;
774c2ffa973SLaxman Dewangan 	config.init_data = pdata->reg_init_data;
7755928f538SLaxman Dewangan 	config.driver_data = max;
7765928f538SLaxman Dewangan 	config.of_node = client->dev.of_node;
7775928f538SLaxman Dewangan 	config.regmap = max->regmap;
7785928f538SLaxman Dewangan 
77948bd226fSLinus Walleij 	/*
78048bd226fSLinus Walleij 	 * Register the regulators
78148bd226fSLinus Walleij 	 * Turn the GPIO descriptor over to the regulator core for
78248bd226fSLinus Walleij 	 * lifecycle management if we pass an ena_gpiod.
78348bd226fSLinus Walleij 	 */
78448bd226fSLinus Walleij 	if (config.ena_gpiod)
78548bd226fSLinus Walleij 		devm_gpiod_unhinge(&client->dev, config.ena_gpiod);
7868d581fd0SSachin Kamat 	rdev = devm_regulator_register(&client->dev, &max->desc, &config);
7875928f538SLaxman Dewangan 	if (IS_ERR(rdev)) {
7885928f538SLaxman Dewangan 		ret = PTR_ERR(rdev);
7895928f538SLaxman Dewangan 		dev_err(max->dev, "regulator register failed, err %d\n", ret);
7905928f538SLaxman Dewangan 		return ret;
7915928f538SLaxman Dewangan 	}
7925928f538SLaxman Dewangan 
793d2d5437bSLaxman Dewangan 	max8973_thermal_init(max);
7945928f538SLaxman Dewangan 	return 0;
7955928f538SLaxman Dewangan }
7965928f538SLaxman Dewangan 
7975928f538SLaxman Dewangan static const struct i2c_device_id max8973_id[] = {
7980f7d6eceSLaxman Dewangan 	{.name = "max8973", .driver_data = MAX8973},
7990f7d6eceSLaxman Dewangan 	{.name = "max77621", .driver_data = MAX77621},
8005928f538SLaxman Dewangan 	{},
8015928f538SLaxman Dewangan };
8025928f538SLaxman Dewangan MODULE_DEVICE_TABLE(i2c, max8973_id);
8035928f538SLaxman Dewangan 
8045928f538SLaxman Dewangan static struct i2c_driver max8973_i2c_driver = {
8055928f538SLaxman Dewangan 	.driver = {
8065928f538SLaxman Dewangan 		.name = "max8973",
807259b93b2SDouglas Anderson 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
8080f7d6eceSLaxman Dewangan 		.of_match_table = of_max8973_match_tbl,
8095928f538SLaxman Dewangan 	},
810*964e1865SUwe Kleine-König 	.probe = max8973_probe,
8115928f538SLaxman Dewangan 	.id_table = max8973_id,
8125928f538SLaxman Dewangan };
8135928f538SLaxman Dewangan 
max8973_init(void)8145928f538SLaxman Dewangan static int __init max8973_init(void)
8155928f538SLaxman Dewangan {
8165928f538SLaxman Dewangan 	return i2c_add_driver(&max8973_i2c_driver);
8175928f538SLaxman Dewangan }
8185928f538SLaxman Dewangan subsys_initcall(max8973_init);
8195928f538SLaxman Dewangan 
max8973_cleanup(void)8205928f538SLaxman Dewangan static void __exit max8973_cleanup(void)
8215928f538SLaxman Dewangan {
8225928f538SLaxman Dewangan 	i2c_del_driver(&max8973_i2c_driver);
8235928f538SLaxman Dewangan }
8245928f538SLaxman Dewangan module_exit(max8973_cleanup);
8255928f538SLaxman Dewangan 
8265928f538SLaxman Dewangan MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
8275928f538SLaxman Dewangan MODULE_DESCRIPTION("MAX8973 voltage regulator driver");
8285928f538SLaxman Dewangan MODULE_LICENSE("GPL v2");
829