Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) // max77802.c - Regulator driver for the Maxim 77802
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) // Copyright (C) 2013-2014 Google, Inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) // Simon Glass <sjg@chromium.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) // Copyright (C) 2012 Samsung Electronics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) // Chiwoong Byun <woong.byun@samsung.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) // Jonghwa Lee <jonghwa3.lee@samsung.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) // This driver is based on max8997.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/bug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/regulator/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/regulator/machine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/regulator/of_regulator.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/mfd/max77686.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/mfd/max77686-private.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <dt-bindings/regulator/maxim,max77802.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) /* Default ramp delay in case it is not manually set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define MAX77802_RAMP_DELAY		100000		/* uV/us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define MAX77802_OPMODE_SHIFT_LDO	6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define MAX77802_OPMODE_BUCK234_SHIFT	4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define MAX77802_OPMODE_MASK		0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define MAX77802_VSEL_MASK		0x3F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define MAX77802_DVS_VSEL_MASK		0xFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define MAX77802_RAMP_RATE_MASK_2BIT	0xC0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define MAX77802_RAMP_RATE_SHIFT_2BIT	6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define MAX77802_RAMP_RATE_MASK_4BIT	0xF0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define MAX77802_RAMP_RATE_SHIFT_4BIT	4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define MAX77802_STATUS_OFF		0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define MAX77802_OFF_PWRREQ		0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define MAX77802_LP_PWRREQ		0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) /* MAX77802 has two register formats: 2-bit and 4-bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) static const unsigned int ramp_table_77802_2bit[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	12500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	25000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	50000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	100000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) static unsigned int ramp_table_77802_4bit[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	1000,	2000,	3030,	4000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	5000,	5880,	7140,	8330,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	9090,	10000,	11110,	12500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	16670,	25000,	50000,	100000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) struct max77802_regulator_prv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	/* Array indexed by regulator id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	unsigned int opmode[MAX77802_REG_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) static inline unsigned int max77802_map_mode(unsigned int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	return mode == MAX77802_OPMODE_NORMAL ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		REGULATOR_MODE_NORMAL : REGULATOR_MODE_STANDBY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) static int max77802_get_opmode_shift(int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	if (id == MAX77802_BUCK1 || (id >= MAX77802_BUCK5 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 				     id <= MAX77802_BUCK10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	if (id >= MAX77802_BUCK2 && id <= MAX77802_BUCK4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		return MAX77802_OPMODE_BUCK234_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	if (id >= MAX77802_LDO1 && id <= MAX77802_LDO35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		return MAX77802_OPMODE_SHIFT_LDO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  * max77802_set_suspend_disable - Disable the regulator during system suspend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  * @rdev: regulator to mark as disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  * All regulators expect LDO 1, 3, 20 and 21 support OFF by PWRREQ.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  * Configure the regulator so the PMIC will turn it OFF during system suspend.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) static int max77802_set_suspend_disable(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	unsigned int val = MAX77802_OFF_PWRREQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	int id = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	int shift = max77802_get_opmode_shift(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	max77802->opmode[id] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 				  rdev->desc->enable_mask, val << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  * Some LDOs support Low Power Mode while the system is running.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)  * LDOs 1, 3, 20, 21.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static int max77802_set_mode(struct regulator_dev *rdev, unsigned int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	int id = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	int shift = max77802_get_opmode_shift(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	case REGULATOR_MODE_STANDBY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		val = MAX77802_OPMODE_LP;	/* ON in Low Power Mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	case REGULATOR_MODE_NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		val = MAX77802_OPMODE_NORMAL;	/* ON in Normal Mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 			 rdev->desc->name, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	max77802->opmode[id] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 				  rdev->desc->enable_mask, val << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static unsigned max77802_get_mode(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	int id = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	return max77802_map_mode(max77802->opmode[id]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  * max77802_set_suspend_mode - set regulator opmode when the system is suspended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  * @rdev: regulator to change mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  * @mode: operating mode to be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)  * Will set the operating mode for the regulators during system suspend.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)  * This function is valid for the three different enable control logics:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)  * Enable Control Logic1 by PWRREQ (BUCK 2-4 and LDOs 2, 4-19, 22-35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)  * Enable Control Logic2 by PWRREQ (LDOs 1, 20, 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)  * Enable Control Logic3 by PWRREQ (LDO 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)  * If setting the regulator mode fails, the function only warns but does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)  * not return an error code to avoid the regulator core to stop setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)  * the operating mode for the remaining regulators.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static int max77802_set_suspend_mode(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 				     unsigned int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	int id = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	int shift = max77802_get_opmode_shift(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	 * If the regulator has been disabled for suspend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	 * then is invalid to try setting a suspend mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	if (max77802->opmode[id] == MAX77802_OFF_PWRREQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		dev_warn(&rdev->dev, "%s: is disabled, mode: 0x%x not set\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 			 rdev->desc->name, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	case REGULATOR_MODE_STANDBY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		 * If the regulator opmode is normal then enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		 * ON in Low Power Mode by PWRREQ. If the mode is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		 * already Low Power then no action is required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		if (max77802->opmode[id] == MAX77802_OPMODE_NORMAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 			val = MAX77802_LP_PWRREQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	case REGULATOR_MODE_NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		 * If the regulator operating mode is Low Power then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		 * normal is not a valid opmode in suspend. If the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		 * mode is already normal then no action is required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		if (max77802->opmode[id] == MAX77802_OPMODE_LP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 			dev_warn(&rdev->dev, "%s: in Low Power: 0x%x invalid\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 				 rdev->desc->name, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			 rdev->desc->name, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 				  rdev->desc->enable_mask, val << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static int max77802_enable(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	int id = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	int shift = max77802_get_opmode_shift(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	if (max77802->opmode[id] == MAX77802_OFF_PWRREQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		max77802->opmode[id] = MAX77802_OPMODE_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 				  rdev->desc->enable_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 				  max77802->opmode[id] << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static int max77802_find_ramp_value(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 				    const unsigned int limits[], int size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 				    unsigned int ramp_delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	for (i = 0; i < size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		if (ramp_delay <= limits[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 			return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	/* Use maximum value for no ramp control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	dev_warn(&rdev->dev, "%s: ramp_delay: %d not supported, setting 100000\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		 rdev->desc->name, ramp_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	return size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /* Used for BUCKs 2-4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static int max77802_set_ramp_delay_2bit(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 					int ramp_delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	int id = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	unsigned int ramp_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	if (id > MAX77802_BUCK4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		dev_warn(&rdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 			 "%s: regulator: ramp delay not supported\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 			 rdev->desc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	ramp_value = max77802_find_ramp_value(rdev, ramp_table_77802_2bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 				ARRAY_SIZE(ramp_table_77802_2bit), ramp_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 				  MAX77802_RAMP_RATE_MASK_2BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 				  ramp_value << MAX77802_RAMP_RATE_SHIFT_2BIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* For BUCK1, 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static int max77802_set_ramp_delay_4bit(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 					    int ramp_delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	unsigned int ramp_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	ramp_value = max77802_find_ramp_value(rdev, ramp_table_77802_4bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 				ARRAY_SIZE(ramp_table_77802_4bit), ramp_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 				  MAX77802_RAMP_RATE_MASK_4BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 				  ramp_value << MAX77802_RAMP_RATE_SHIFT_4BIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)  * LDOs 2, 4-19, 22-35
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static const struct regulator_ops max77802_ldo_ops_logic1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	.list_voltage		= regulator_list_voltage_linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	.map_voltage		= regulator_map_voltage_linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	.is_enabled		= regulator_is_enabled_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	.enable			= max77802_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	.disable		= regulator_disable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	.set_suspend_disable	= max77802_set_suspend_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	.set_suspend_mode	= max77802_set_suspend_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)  * LDOs 1, 20, 21, 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static const struct regulator_ops max77802_ldo_ops_logic2 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	.list_voltage		= regulator_list_voltage_linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	.map_voltage		= regulator_map_voltage_linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	.is_enabled		= regulator_is_enabled_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	.enable			= max77802_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	.disable		= regulator_disable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	.set_mode		= max77802_set_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	.get_mode		= max77802_get_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	.set_suspend_mode	= max77802_set_suspend_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /* BUCKS 1, 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static const struct regulator_ops max77802_buck_16_dvs_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	.list_voltage		= regulator_list_voltage_linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	.map_voltage		= regulator_map_voltage_linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	.is_enabled		= regulator_is_enabled_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	.enable			= max77802_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	.disable		= regulator_disable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	.set_ramp_delay		= max77802_set_ramp_delay_4bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	.set_suspend_disable	= max77802_set_suspend_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /* BUCKs 2-4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static const struct regulator_ops max77802_buck_234_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	.list_voltage		= regulator_list_voltage_linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	.map_voltage		= regulator_map_voltage_linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	.is_enabled		= regulator_is_enabled_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	.enable			= max77802_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	.disable		= regulator_disable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	.set_ramp_delay		= max77802_set_ramp_delay_2bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	.set_suspend_disable	= max77802_set_suspend_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	.set_suspend_mode	= max77802_set_suspend_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) /* BUCKs 5, 7-10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static const struct regulator_ops max77802_buck_dvs_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	.list_voltage		= regulator_list_voltage_linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	.map_voltage		= regulator_map_voltage_linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	.is_enabled		= regulator_is_enabled_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	.enable			= max77802_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	.disable		= regulator_disable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	.set_ramp_delay		= max77802_set_ramp_delay_2bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	.set_suspend_disable	= max77802_set_suspend_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* LDOs 3-7, 9-14, 18-26, 28, 29, 32-34 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) #define regulator_77802_desc_p_ldo(num, supply, log)	{		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	.name		= "LDO"#num,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	.of_match	= of_match_ptr("LDO"#num),			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	.regulators_node	= of_match_ptr("regulators"),		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	.id		= MAX77802_LDO##num,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	.supply_name	= "inl"#supply,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	.ops		= &max77802_ldo_ops_logic##log,			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	.type		= REGULATOR_VOLTAGE,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	.owner		= THIS_MODULE,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	.min_uV		= 800000,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	.uV_step	= 50000,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	.ramp_delay	= MAX77802_RAMP_DELAY,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	.n_voltages	= 1 << 6,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	.vsel_reg	= MAX77802_REG_LDO1CTRL1 + num - 1,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	.vsel_mask	= MAX77802_VSEL_MASK,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	.enable_reg	= MAX77802_REG_LDO1CTRL1 + num - 1,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	.enable_mask	= MAX77802_OPMODE_MASK << MAX77802_OPMODE_SHIFT_LDO, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	.of_map_mode	= max77802_map_mode,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /* LDOs 1, 2, 8, 15, 17, 27, 30, 35 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) #define regulator_77802_desc_n_ldo(num, supply, log)   {		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	.name		= "LDO"#num,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	.of_match	= of_match_ptr("LDO"#num),			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	.regulators_node	= of_match_ptr("regulators"),		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	.id		= MAX77802_LDO##num,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	.supply_name	= "inl"#supply,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	.ops		= &max77802_ldo_ops_logic##log,			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	.type		= REGULATOR_VOLTAGE,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	.owner		= THIS_MODULE,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	.min_uV		= 800000,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	.uV_step	= 25000,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	.ramp_delay	= MAX77802_RAMP_DELAY,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	.n_voltages	= 1 << 6,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	.vsel_reg	= MAX77802_REG_LDO1CTRL1 + num - 1,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	.vsel_mask	= MAX77802_VSEL_MASK,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	.enable_reg	= MAX77802_REG_LDO1CTRL1 + num - 1,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	.enable_mask	= MAX77802_OPMODE_MASK << MAX77802_OPMODE_SHIFT_LDO, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	.of_map_mode	= max77802_map_mode,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /* BUCKs 1, 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) #define regulator_77802_desc_16_buck(num)	{		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	.name		= "BUCK"#num,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	.of_match	= of_match_ptr("BUCK"#num),			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	.regulators_node	= of_match_ptr("regulators"),		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	.id		= MAX77802_BUCK##num,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	.supply_name	= "inb"#num,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	.ops		= &max77802_buck_16_dvs_ops,			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	.type		= REGULATOR_VOLTAGE,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	.owner		= THIS_MODULE,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	.min_uV		= 612500,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	.uV_step	= 6250,						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	.ramp_delay	= MAX77802_RAMP_DELAY,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	.n_voltages	= 1 << 8,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	.vsel_reg	= MAX77802_REG_BUCK ## num ## DVS1,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	.vsel_mask	= MAX77802_DVS_VSEL_MASK,			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	.enable_reg	= MAX77802_REG_BUCK ## num ## CTRL,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	.enable_mask	= MAX77802_OPMODE_MASK,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	.of_map_mode	= max77802_map_mode,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /* BUCKS 2-4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) #define regulator_77802_desc_234_buck(num)	{		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	.name		= "BUCK"#num,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	.of_match	= of_match_ptr("BUCK"#num),			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	.regulators_node	= of_match_ptr("regulators"),		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	.id		= MAX77802_BUCK##num,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	.supply_name	= "inb"#num,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	.ops		= &max77802_buck_234_ops,			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	.type		= REGULATOR_VOLTAGE,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	.owner		= THIS_MODULE,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	.min_uV		= 600000,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	.uV_step	= 6250,						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	.ramp_delay	= MAX77802_RAMP_DELAY,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	.n_voltages	= 0x91,						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	.vsel_reg	= MAX77802_REG_BUCK ## num ## DVS1,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	.vsel_mask	= MAX77802_DVS_VSEL_MASK,			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	.enable_reg	= MAX77802_REG_BUCK ## num ## CTRL1,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	.enable_mask	= MAX77802_OPMODE_MASK <<			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 				MAX77802_OPMODE_BUCK234_SHIFT,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	.of_map_mode	= max77802_map_mode,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) /* BUCK 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) #define regulator_77802_desc_buck5(num)		{		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	.name		= "BUCK"#num,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	.of_match	= of_match_ptr("BUCK"#num),			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	.regulators_node	= of_match_ptr("regulators"),		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	.id		= MAX77802_BUCK##num,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	.supply_name	= "inb"#num,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	.ops		= &max77802_buck_dvs_ops,			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	.type		= REGULATOR_VOLTAGE,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	.owner		= THIS_MODULE,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	.min_uV		= 750000,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	.uV_step	= 50000,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	.ramp_delay	= MAX77802_RAMP_DELAY,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	.n_voltages	= 1 << 6,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	.vsel_reg	= MAX77802_REG_BUCK5OUT,			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	.vsel_mask	= MAX77802_VSEL_MASK,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	.enable_reg	= MAX77802_REG_BUCK5CTRL,			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	.enable_mask	= MAX77802_OPMODE_MASK,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	.of_map_mode	= max77802_map_mode,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) /* BUCKs 7-10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) #define regulator_77802_desc_buck7_10(num)	{		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	.name		= "BUCK"#num,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	.of_match	= of_match_ptr("BUCK"#num),			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	.regulators_node	= of_match_ptr("regulators"),		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	.id		= MAX77802_BUCK##num,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	.supply_name	= "inb"#num,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	.ops		= &max77802_buck_dvs_ops,			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	.type		= REGULATOR_VOLTAGE,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	.owner		= THIS_MODULE,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	.min_uV		= 750000,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	.uV_step	= 50000,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	.ramp_delay	= MAX77802_RAMP_DELAY,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	.n_voltages	= 1 << 6,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	.vsel_reg	= MAX77802_REG_BUCK7OUT + (num - 7) * 3,	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	.vsel_mask	= MAX77802_VSEL_MASK,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	.enable_reg	= MAX77802_REG_BUCK7CTRL + (num - 7) * 3,	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	.enable_mask	= MAX77802_OPMODE_MASK,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	.of_map_mode	= max77802_map_mode,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) static const struct regulator_desc regulators[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	regulator_77802_desc_16_buck(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	regulator_77802_desc_234_buck(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	regulator_77802_desc_234_buck(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	regulator_77802_desc_234_buck(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	regulator_77802_desc_buck5(5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	regulator_77802_desc_16_buck(6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	regulator_77802_desc_buck7_10(7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	regulator_77802_desc_buck7_10(8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	regulator_77802_desc_buck7_10(9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	regulator_77802_desc_buck7_10(10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	regulator_77802_desc_n_ldo(1, 10, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	regulator_77802_desc_n_ldo(2, 10, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	regulator_77802_desc_p_ldo(3, 3, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	regulator_77802_desc_p_ldo(4, 6, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	regulator_77802_desc_p_ldo(5, 3, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	regulator_77802_desc_p_ldo(6, 3, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	regulator_77802_desc_p_ldo(7, 3, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	regulator_77802_desc_n_ldo(8, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	regulator_77802_desc_p_ldo(9, 5, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	regulator_77802_desc_p_ldo(10, 4, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	regulator_77802_desc_p_ldo(11, 4, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	regulator_77802_desc_p_ldo(12, 9, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	regulator_77802_desc_p_ldo(13, 4, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	regulator_77802_desc_p_ldo(14, 4, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	regulator_77802_desc_n_ldo(15, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	regulator_77802_desc_n_ldo(17, 2, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	regulator_77802_desc_p_ldo(18, 7, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	regulator_77802_desc_p_ldo(19, 5, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	regulator_77802_desc_p_ldo(20, 7, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	regulator_77802_desc_p_ldo(21, 6, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	regulator_77802_desc_p_ldo(23, 9, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	regulator_77802_desc_p_ldo(24, 6, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	regulator_77802_desc_p_ldo(25, 9, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	regulator_77802_desc_p_ldo(26, 9, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	regulator_77802_desc_n_ldo(27, 2, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	regulator_77802_desc_p_ldo(28, 7, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	regulator_77802_desc_p_ldo(29, 7, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	regulator_77802_desc_n_ldo(30, 2, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	regulator_77802_desc_p_ldo(32, 9, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	regulator_77802_desc_p_ldo(33, 6, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	regulator_77802_desc_p_ldo(34, 9, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	regulator_77802_desc_n_ldo(35, 2, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) static int max77802_pmic_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	struct max77802_regulator_prv *max77802;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	int i, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	struct regulator_config config = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	max77802 = devm_kzalloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 				sizeof(struct max77802_regulator_prv),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 				GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	if (!max77802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	config.dev = iodev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	config.regmap = iodev->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	config.driver_data = max77802;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	platform_set_drvdata(pdev, max77802);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	for (i = 0; i < MAX77802_REG_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		struct regulator_dev *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		int id = regulators[i].id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		int shift = max77802_get_opmode_shift(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		ret = regmap_read(iodev->regmap, regulators[i].enable_reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 			dev_warn(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 				"cannot read current mode for %d\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 			val = MAX77802_OPMODE_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 			val = val >> shift & MAX77802_OPMODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		 * If the regulator is disabled and the system warm rebooted,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 		 * the hardware reports OFF as the regulator operating mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		 * Default to operating mode NORMAL in that case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		if (val == MAX77802_STATUS_OFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 			max77802->opmode[id] = MAX77802_OPMODE_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 			max77802->opmode[id] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 		rdev = devm_regulator_register(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 					       &regulators[i], &config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		if (IS_ERR(rdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 			ret = PTR_ERR(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 			dev_err(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 				"regulator init failed for %d: %d\n", i, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) static const struct platform_device_id max77802_pmic_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	{"max77802-pmic", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) MODULE_DEVICE_TABLE(platform, max77802_pmic_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static struct platform_driver max77802_pmic_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 		.name = "max77802-pmic",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	.probe = max77802_pmic_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	.id_table = max77802_pmic_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) module_platform_driver(max77802_pmic_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) MODULE_DESCRIPTION("MAXIM 77802 Regulator Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) MODULE_AUTHOR("Simon Glass <sjg@chromium.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) MODULE_LICENSE("GPL");