18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci// Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci#define pr_fmt(fmt) "%s: " fmt, __func__
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <linux/err.h>
78c2ecf20Sopenharmony_ci#include <linux/kernel.h>
88c2ecf20Sopenharmony_ci#include <linux/module.h>
98c2ecf20Sopenharmony_ci#include <linux/of.h>
108c2ecf20Sopenharmony_ci#include <linux/of_device.h>
118c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
128c2ecf20Sopenharmony_ci#include <linux/slab.h>
138c2ecf20Sopenharmony_ci#include <linux/string.h>
148c2ecf20Sopenharmony_ci#include <linux/regulator/driver.h>
158c2ecf20Sopenharmony_ci#include <linux/regulator/machine.h>
168c2ecf20Sopenharmony_ci#include <linux/regulator/of_regulator.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#include <soc/qcom/cmd-db.h>
198c2ecf20Sopenharmony_ci#include <soc/qcom/rpmh.h>
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci/**
248c2ecf20Sopenharmony_ci * enum rpmh_regulator_type - supported RPMh accelerator types
258c2ecf20Sopenharmony_ci * @VRM:	RPMh VRM accelerator which supports voting on enable, voltage,
268c2ecf20Sopenharmony_ci *		and mode of LDO, SMPS, and BOB type PMIC regulators.
278c2ecf20Sopenharmony_ci * @XOB:	RPMh XOB accelerator which supports voting on the enable state
288c2ecf20Sopenharmony_ci *		of PMIC regulators.
298c2ecf20Sopenharmony_ci */
308c2ecf20Sopenharmony_cienum rpmh_regulator_type {
318c2ecf20Sopenharmony_ci	VRM,
328c2ecf20Sopenharmony_ci	XOB,
338c2ecf20Sopenharmony_ci};
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci#define RPMH_REGULATOR_REG_VRM_VOLTAGE		0x0
368c2ecf20Sopenharmony_ci#define RPMH_REGULATOR_REG_ENABLE		0x4
378c2ecf20Sopenharmony_ci#define RPMH_REGULATOR_REG_VRM_MODE		0x8
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci#define PMIC4_LDO_MODE_RETENTION		4
408c2ecf20Sopenharmony_ci#define PMIC4_LDO_MODE_LPM			5
418c2ecf20Sopenharmony_ci#define PMIC4_LDO_MODE_HPM			7
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci#define PMIC4_SMPS_MODE_RETENTION		4
448c2ecf20Sopenharmony_ci#define PMIC4_SMPS_MODE_PFM			5
458c2ecf20Sopenharmony_ci#define PMIC4_SMPS_MODE_AUTO			6
468c2ecf20Sopenharmony_ci#define PMIC4_SMPS_MODE_PWM			7
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci#define PMIC4_BOB_MODE_PASS			0
498c2ecf20Sopenharmony_ci#define PMIC4_BOB_MODE_PFM			1
508c2ecf20Sopenharmony_ci#define PMIC4_BOB_MODE_AUTO			2
518c2ecf20Sopenharmony_ci#define PMIC4_BOB_MODE_PWM			3
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci#define PMIC5_LDO_MODE_RETENTION		3
548c2ecf20Sopenharmony_ci#define PMIC5_LDO_MODE_LPM			4
558c2ecf20Sopenharmony_ci#define PMIC5_LDO_MODE_HPM			7
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci#define PMIC5_SMPS_MODE_RETENTION		3
588c2ecf20Sopenharmony_ci#define PMIC5_SMPS_MODE_PFM			4
598c2ecf20Sopenharmony_ci#define PMIC5_SMPS_MODE_AUTO			6
608c2ecf20Sopenharmony_ci#define PMIC5_SMPS_MODE_PWM			7
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci#define PMIC5_BOB_MODE_PASS			2
638c2ecf20Sopenharmony_ci#define PMIC5_BOB_MODE_PFM			4
648c2ecf20Sopenharmony_ci#define PMIC5_BOB_MODE_AUTO			6
658c2ecf20Sopenharmony_ci#define PMIC5_BOB_MODE_PWM			7
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci/**
688c2ecf20Sopenharmony_ci * struct rpmh_vreg_hw_data - RPMh regulator hardware configurations
698c2ecf20Sopenharmony_ci * @regulator_type:		RPMh accelerator type used to manage this
708c2ecf20Sopenharmony_ci *				regulator
718c2ecf20Sopenharmony_ci * @ops:			Pointer to regulator ops callback structure
728c2ecf20Sopenharmony_ci * @voltage_range:		The single range of voltages supported by this
738c2ecf20Sopenharmony_ci *				PMIC regulator type
748c2ecf20Sopenharmony_ci * @n_voltages:			The number of unique voltage set points defined
758c2ecf20Sopenharmony_ci *				by voltage_range
768c2ecf20Sopenharmony_ci * @hpm_min_load_uA:		Minimum load current in microamps that requires
778c2ecf20Sopenharmony_ci *				high power mode (HPM) operation.  This is used
788c2ecf20Sopenharmony_ci *				for LDO hardware type regulators only.
798c2ecf20Sopenharmony_ci * @pmic_mode_map:		Array indexed by regulator framework mode
808c2ecf20Sopenharmony_ci *				containing PMIC hardware modes.  Must be large
818c2ecf20Sopenharmony_ci *				enough to index all framework modes supported
828c2ecf20Sopenharmony_ci *				by this regulator hardware type.
838c2ecf20Sopenharmony_ci * @of_map_mode:		Maps an RPMH_REGULATOR_MODE_* mode value defined
848c2ecf20Sopenharmony_ci *				in device tree to a regulator framework mode
858c2ecf20Sopenharmony_ci */
868c2ecf20Sopenharmony_cistruct rpmh_vreg_hw_data {
878c2ecf20Sopenharmony_ci	enum rpmh_regulator_type		regulator_type;
888c2ecf20Sopenharmony_ci	const struct regulator_ops		*ops;
898c2ecf20Sopenharmony_ci	const struct linear_range	voltage_range;
908c2ecf20Sopenharmony_ci	int					n_voltages;
918c2ecf20Sopenharmony_ci	int					hpm_min_load_uA;
928c2ecf20Sopenharmony_ci	const int				*pmic_mode_map;
938c2ecf20Sopenharmony_ci	unsigned int			      (*of_map_mode)(unsigned int mode);
948c2ecf20Sopenharmony_ci};
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci/**
978c2ecf20Sopenharmony_ci * struct rpmh_vreg - individual RPMh regulator data structure encapsulating a
988c2ecf20Sopenharmony_ci *		single regulator device
998c2ecf20Sopenharmony_ci * @dev:			Device pointer for the top-level PMIC RPMh
1008c2ecf20Sopenharmony_ci *				regulator parent device.  This is used as a
1018c2ecf20Sopenharmony_ci *				handle in RPMh write requests.
1028c2ecf20Sopenharmony_ci * @addr:			Base address of the regulator resource within
1038c2ecf20Sopenharmony_ci *				an RPMh accelerator
1048c2ecf20Sopenharmony_ci * @rdesc:			Regulator descriptor
1058c2ecf20Sopenharmony_ci * @hw_data:			PMIC regulator configuration data for this RPMh
1068c2ecf20Sopenharmony_ci *				regulator
1078c2ecf20Sopenharmony_ci * @always_wait_for_ack:	Boolean flag indicating if a request must always
1088c2ecf20Sopenharmony_ci *				wait for an ACK from RPMh before continuing even
1098c2ecf20Sopenharmony_ci *				if it corresponds to a strictly lower power
1108c2ecf20Sopenharmony_ci *				state (e.g. enabled --> disabled).
1118c2ecf20Sopenharmony_ci * @enabled:			Flag indicating if the regulator is enabled or
1128c2ecf20Sopenharmony_ci *				not
1138c2ecf20Sopenharmony_ci * @bypassed:			Boolean indicating if the regulator is in
1148c2ecf20Sopenharmony_ci *				bypass (pass-through) mode or not.  This is
1158c2ecf20Sopenharmony_ci *				only used by BOB rpmh-regulator resources.
1168c2ecf20Sopenharmony_ci * @voltage_selector:		Selector used for get_voltage_sel() and
1178c2ecf20Sopenharmony_ci *				set_voltage_sel() callbacks
1188c2ecf20Sopenharmony_ci * @mode:			RPMh VRM regulator current framework mode
1198c2ecf20Sopenharmony_ci */
1208c2ecf20Sopenharmony_cistruct rpmh_vreg {
1218c2ecf20Sopenharmony_ci	struct device			*dev;
1228c2ecf20Sopenharmony_ci	u32				addr;
1238c2ecf20Sopenharmony_ci	struct regulator_desc		rdesc;
1248c2ecf20Sopenharmony_ci	const struct rpmh_vreg_hw_data	*hw_data;
1258c2ecf20Sopenharmony_ci	bool				always_wait_for_ack;
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci	int				enabled;
1288c2ecf20Sopenharmony_ci	bool				bypassed;
1298c2ecf20Sopenharmony_ci	int				voltage_selector;
1308c2ecf20Sopenharmony_ci	unsigned int			mode;
1318c2ecf20Sopenharmony_ci};
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci/**
1348c2ecf20Sopenharmony_ci * struct rpmh_vreg_init_data - initialization data for an RPMh regulator
1358c2ecf20Sopenharmony_ci * @name:			Name for the regulator which also corresponds
1368c2ecf20Sopenharmony_ci *				to the device tree subnode name of the regulator
1378c2ecf20Sopenharmony_ci * @resource_name:		RPMh regulator resource name format string.
1388c2ecf20Sopenharmony_ci *				This must include exactly one field: '%s' which
1398c2ecf20Sopenharmony_ci *				is filled at run-time with the PMIC ID provided
1408c2ecf20Sopenharmony_ci *				by device tree property qcom,pmic-id.  Example:
1418c2ecf20Sopenharmony_ci *				"ldo%s1" for RPMh resource "ldoa1".
1428c2ecf20Sopenharmony_ci * @supply_name:		Parent supply regulator name
1438c2ecf20Sopenharmony_ci * @hw_data:			Configuration data for this PMIC regulator type
1448c2ecf20Sopenharmony_ci */
1458c2ecf20Sopenharmony_cistruct rpmh_vreg_init_data {
1468c2ecf20Sopenharmony_ci	const char			*name;
1478c2ecf20Sopenharmony_ci	const char			*resource_name;
1488c2ecf20Sopenharmony_ci	const char			*supply_name;
1498c2ecf20Sopenharmony_ci	const struct rpmh_vreg_hw_data	*hw_data;
1508c2ecf20Sopenharmony_ci};
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci/**
1538c2ecf20Sopenharmony_ci * rpmh_regulator_send_request() - send the request to RPMh
1548c2ecf20Sopenharmony_ci * @vreg:		Pointer to the RPMh regulator
1558c2ecf20Sopenharmony_ci * @cmd:		Pointer to the RPMh command to send
1568c2ecf20Sopenharmony_ci * @wait_for_ack:	Boolean indicating if execution must wait until the
1578c2ecf20Sopenharmony_ci *			request has been acknowledged as complete
1588c2ecf20Sopenharmony_ci *
1598c2ecf20Sopenharmony_ci * Return: 0 on success, errno on failure
1608c2ecf20Sopenharmony_ci */
1618c2ecf20Sopenharmony_cistatic int rpmh_regulator_send_request(struct rpmh_vreg *vreg,
1628c2ecf20Sopenharmony_ci			struct tcs_cmd *cmd, bool wait_for_ack)
1638c2ecf20Sopenharmony_ci{
1648c2ecf20Sopenharmony_ci	int ret;
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci	if (wait_for_ack || vreg->always_wait_for_ack)
1678c2ecf20Sopenharmony_ci		ret = rpmh_write(vreg->dev, RPMH_ACTIVE_ONLY_STATE, cmd, 1);
1688c2ecf20Sopenharmony_ci	else
1698c2ecf20Sopenharmony_ci		ret = rpmh_write_async(vreg->dev, RPMH_ACTIVE_ONLY_STATE, cmd,
1708c2ecf20Sopenharmony_ci					1);
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci	return ret;
1738c2ecf20Sopenharmony_ci}
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_cistatic int _rpmh_regulator_vrm_set_voltage_sel(struct regulator_dev *rdev,
1768c2ecf20Sopenharmony_ci				unsigned int selector, bool wait_for_ack)
1778c2ecf20Sopenharmony_ci{
1788c2ecf20Sopenharmony_ci	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
1798c2ecf20Sopenharmony_ci	struct tcs_cmd cmd = {
1808c2ecf20Sopenharmony_ci		.addr = vreg->addr + RPMH_REGULATOR_REG_VRM_VOLTAGE,
1818c2ecf20Sopenharmony_ci	};
1828c2ecf20Sopenharmony_ci	int ret;
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci	/* VRM voltage control register is set with voltage in millivolts. */
1858c2ecf20Sopenharmony_ci	cmd.data = DIV_ROUND_UP(regulator_list_voltage_linear_range(rdev,
1868c2ecf20Sopenharmony_ci							selector), 1000);
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ci	ret = rpmh_regulator_send_request(vreg, &cmd, wait_for_ack);
1898c2ecf20Sopenharmony_ci	if (!ret)
1908c2ecf20Sopenharmony_ci		vreg->voltage_selector = selector;
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci	return ret;
1938c2ecf20Sopenharmony_ci}
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_cistatic int rpmh_regulator_vrm_set_voltage_sel(struct regulator_dev *rdev,
1968c2ecf20Sopenharmony_ci					unsigned int selector)
1978c2ecf20Sopenharmony_ci{
1988c2ecf20Sopenharmony_ci	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci	if (vreg->enabled == -EINVAL) {
2018c2ecf20Sopenharmony_ci		/*
2028c2ecf20Sopenharmony_ci		 * Cache the voltage and send it later when the regulator is
2038c2ecf20Sopenharmony_ci		 * enabled or disabled.
2048c2ecf20Sopenharmony_ci		 */
2058c2ecf20Sopenharmony_ci		vreg->voltage_selector = selector;
2068c2ecf20Sopenharmony_ci		return 0;
2078c2ecf20Sopenharmony_ci	}
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ci	return _rpmh_regulator_vrm_set_voltage_sel(rdev, selector,
2108c2ecf20Sopenharmony_ci					selector > vreg->voltage_selector);
2118c2ecf20Sopenharmony_ci}
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_cistatic int rpmh_regulator_vrm_get_voltage_sel(struct regulator_dev *rdev)
2148c2ecf20Sopenharmony_ci{
2158c2ecf20Sopenharmony_ci	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
2168c2ecf20Sopenharmony_ci
2178c2ecf20Sopenharmony_ci	return vreg->voltage_selector;
2188c2ecf20Sopenharmony_ci}
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_cistatic int rpmh_regulator_is_enabled(struct regulator_dev *rdev)
2218c2ecf20Sopenharmony_ci{
2228c2ecf20Sopenharmony_ci	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_ci	return vreg->enabled;
2258c2ecf20Sopenharmony_ci}
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_cistatic int rpmh_regulator_set_enable_state(struct regulator_dev *rdev,
2288c2ecf20Sopenharmony_ci					bool enable)
2298c2ecf20Sopenharmony_ci{
2308c2ecf20Sopenharmony_ci	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
2318c2ecf20Sopenharmony_ci	struct tcs_cmd cmd = {
2328c2ecf20Sopenharmony_ci		.addr = vreg->addr + RPMH_REGULATOR_REG_ENABLE,
2338c2ecf20Sopenharmony_ci		.data = enable,
2348c2ecf20Sopenharmony_ci	};
2358c2ecf20Sopenharmony_ci	int ret;
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_ci	if (vreg->enabled == -EINVAL &&
2388c2ecf20Sopenharmony_ci	    vreg->voltage_selector != -ENOTRECOVERABLE) {
2398c2ecf20Sopenharmony_ci		ret = _rpmh_regulator_vrm_set_voltage_sel(rdev,
2408c2ecf20Sopenharmony_ci						vreg->voltage_selector, true);
2418c2ecf20Sopenharmony_ci		if (ret < 0)
2428c2ecf20Sopenharmony_ci			return ret;
2438c2ecf20Sopenharmony_ci	}
2448c2ecf20Sopenharmony_ci
2458c2ecf20Sopenharmony_ci	ret = rpmh_regulator_send_request(vreg, &cmd, enable);
2468c2ecf20Sopenharmony_ci	if (!ret)
2478c2ecf20Sopenharmony_ci		vreg->enabled = enable;
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_ci	return ret;
2508c2ecf20Sopenharmony_ci}
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_cistatic int rpmh_regulator_enable(struct regulator_dev *rdev)
2538c2ecf20Sopenharmony_ci{
2548c2ecf20Sopenharmony_ci	return rpmh_regulator_set_enable_state(rdev, true);
2558c2ecf20Sopenharmony_ci}
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_cistatic int rpmh_regulator_disable(struct regulator_dev *rdev)
2588c2ecf20Sopenharmony_ci{
2598c2ecf20Sopenharmony_ci	return rpmh_regulator_set_enable_state(rdev, false);
2608c2ecf20Sopenharmony_ci}
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_cistatic int rpmh_regulator_vrm_set_mode_bypass(struct rpmh_vreg *vreg,
2638c2ecf20Sopenharmony_ci					unsigned int mode, bool bypassed)
2648c2ecf20Sopenharmony_ci{
2658c2ecf20Sopenharmony_ci	struct tcs_cmd cmd = {
2668c2ecf20Sopenharmony_ci		.addr = vreg->addr + RPMH_REGULATOR_REG_VRM_MODE,
2678c2ecf20Sopenharmony_ci	};
2688c2ecf20Sopenharmony_ci	int pmic_mode;
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_ci	if (mode > REGULATOR_MODE_STANDBY)
2718c2ecf20Sopenharmony_ci		return -EINVAL;
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_ci	pmic_mode = vreg->hw_data->pmic_mode_map[mode];
2748c2ecf20Sopenharmony_ci	if (pmic_mode < 0)
2758c2ecf20Sopenharmony_ci		return pmic_mode;
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ci	if (bypassed)
2788c2ecf20Sopenharmony_ci		cmd.data = PMIC4_BOB_MODE_PASS;
2798c2ecf20Sopenharmony_ci	else
2808c2ecf20Sopenharmony_ci		cmd.data = pmic_mode;
2818c2ecf20Sopenharmony_ci
2828c2ecf20Sopenharmony_ci	return rpmh_regulator_send_request(vreg, &cmd, true);
2838c2ecf20Sopenharmony_ci}
2848c2ecf20Sopenharmony_ci
2858c2ecf20Sopenharmony_cistatic int rpmh_regulator_vrm_set_mode(struct regulator_dev *rdev,
2868c2ecf20Sopenharmony_ci					unsigned int mode)
2878c2ecf20Sopenharmony_ci{
2888c2ecf20Sopenharmony_ci	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
2898c2ecf20Sopenharmony_ci	int ret;
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_ci	if (mode == vreg->mode)
2928c2ecf20Sopenharmony_ci		return 0;
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_ci	ret = rpmh_regulator_vrm_set_mode_bypass(vreg, mode, vreg->bypassed);
2958c2ecf20Sopenharmony_ci	if (!ret)
2968c2ecf20Sopenharmony_ci		vreg->mode = mode;
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci	return ret;
2998c2ecf20Sopenharmony_ci}
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_cistatic unsigned int rpmh_regulator_vrm_get_mode(struct regulator_dev *rdev)
3028c2ecf20Sopenharmony_ci{
3038c2ecf20Sopenharmony_ci	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
3048c2ecf20Sopenharmony_ci
3058c2ecf20Sopenharmony_ci	return vreg->mode;
3068c2ecf20Sopenharmony_ci}
3078c2ecf20Sopenharmony_ci
3088c2ecf20Sopenharmony_ci/**
3098c2ecf20Sopenharmony_ci * rpmh_regulator_vrm_set_load() - set the regulator mode based upon the load
3108c2ecf20Sopenharmony_ci *		current requested
3118c2ecf20Sopenharmony_ci * @rdev:		Regulator device pointer for the rpmh-regulator
3128c2ecf20Sopenharmony_ci * @load_uA:		Aggregated load current in microamps
3138c2ecf20Sopenharmony_ci *
3148c2ecf20Sopenharmony_ci * This function is used in the regulator_ops for VRM type RPMh regulator
3158c2ecf20Sopenharmony_ci * devices.
3168c2ecf20Sopenharmony_ci *
3178c2ecf20Sopenharmony_ci * Return: 0 on success, errno on failure
3188c2ecf20Sopenharmony_ci */
3198c2ecf20Sopenharmony_cistatic int rpmh_regulator_vrm_set_load(struct regulator_dev *rdev, int load_uA)
3208c2ecf20Sopenharmony_ci{
3218c2ecf20Sopenharmony_ci	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
3228c2ecf20Sopenharmony_ci	unsigned int mode;
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_ci	if (load_uA >= vreg->hw_data->hpm_min_load_uA)
3258c2ecf20Sopenharmony_ci		mode = REGULATOR_MODE_NORMAL;
3268c2ecf20Sopenharmony_ci	else
3278c2ecf20Sopenharmony_ci		mode = REGULATOR_MODE_IDLE;
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_ci	return rpmh_regulator_vrm_set_mode(rdev, mode);
3308c2ecf20Sopenharmony_ci}
3318c2ecf20Sopenharmony_ci
3328c2ecf20Sopenharmony_cistatic int rpmh_regulator_vrm_set_bypass(struct regulator_dev *rdev,
3338c2ecf20Sopenharmony_ci				bool enable)
3348c2ecf20Sopenharmony_ci{
3358c2ecf20Sopenharmony_ci	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
3368c2ecf20Sopenharmony_ci	int ret;
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci	if (vreg->bypassed == enable)
3398c2ecf20Sopenharmony_ci		return 0;
3408c2ecf20Sopenharmony_ci
3418c2ecf20Sopenharmony_ci	ret = rpmh_regulator_vrm_set_mode_bypass(vreg, vreg->mode, enable);
3428c2ecf20Sopenharmony_ci	if (!ret)
3438c2ecf20Sopenharmony_ci		vreg->bypassed = enable;
3448c2ecf20Sopenharmony_ci
3458c2ecf20Sopenharmony_ci	return ret;
3468c2ecf20Sopenharmony_ci}
3478c2ecf20Sopenharmony_ci
3488c2ecf20Sopenharmony_cistatic int rpmh_regulator_vrm_get_bypass(struct regulator_dev *rdev,
3498c2ecf20Sopenharmony_ci				bool *enable)
3508c2ecf20Sopenharmony_ci{
3518c2ecf20Sopenharmony_ci	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_ci	*enable = vreg->bypassed;
3548c2ecf20Sopenharmony_ci
3558c2ecf20Sopenharmony_ci	return 0;
3568c2ecf20Sopenharmony_ci}
3578c2ecf20Sopenharmony_ci
3588c2ecf20Sopenharmony_cistatic const struct regulator_ops rpmh_regulator_vrm_ops = {
3598c2ecf20Sopenharmony_ci	.enable			= rpmh_regulator_enable,
3608c2ecf20Sopenharmony_ci	.disable		= rpmh_regulator_disable,
3618c2ecf20Sopenharmony_ci	.is_enabled		= rpmh_regulator_is_enabled,
3628c2ecf20Sopenharmony_ci	.set_voltage_sel	= rpmh_regulator_vrm_set_voltage_sel,
3638c2ecf20Sopenharmony_ci	.get_voltage_sel	= rpmh_regulator_vrm_get_voltage_sel,
3648c2ecf20Sopenharmony_ci	.list_voltage		= regulator_list_voltage_linear_range,
3658c2ecf20Sopenharmony_ci	.set_mode		= rpmh_regulator_vrm_set_mode,
3668c2ecf20Sopenharmony_ci	.get_mode		= rpmh_regulator_vrm_get_mode,
3678c2ecf20Sopenharmony_ci};
3688c2ecf20Sopenharmony_ci
3698c2ecf20Sopenharmony_cistatic const struct regulator_ops rpmh_regulator_vrm_drms_ops = {
3708c2ecf20Sopenharmony_ci	.enable			= rpmh_regulator_enable,
3718c2ecf20Sopenharmony_ci	.disable		= rpmh_regulator_disable,
3728c2ecf20Sopenharmony_ci	.is_enabled		= rpmh_regulator_is_enabled,
3738c2ecf20Sopenharmony_ci	.set_voltage_sel	= rpmh_regulator_vrm_set_voltage_sel,
3748c2ecf20Sopenharmony_ci	.get_voltage_sel	= rpmh_regulator_vrm_get_voltage_sel,
3758c2ecf20Sopenharmony_ci	.list_voltage		= regulator_list_voltage_linear_range,
3768c2ecf20Sopenharmony_ci	.set_mode		= rpmh_regulator_vrm_set_mode,
3778c2ecf20Sopenharmony_ci	.get_mode		= rpmh_regulator_vrm_get_mode,
3788c2ecf20Sopenharmony_ci	.set_load		= rpmh_regulator_vrm_set_load,
3798c2ecf20Sopenharmony_ci};
3808c2ecf20Sopenharmony_ci
3818c2ecf20Sopenharmony_cistatic const struct regulator_ops rpmh_regulator_vrm_bypass_ops = {
3828c2ecf20Sopenharmony_ci	.enable			= rpmh_regulator_enable,
3838c2ecf20Sopenharmony_ci	.disable		= rpmh_regulator_disable,
3848c2ecf20Sopenharmony_ci	.is_enabled		= rpmh_regulator_is_enabled,
3858c2ecf20Sopenharmony_ci	.set_voltage_sel	= rpmh_regulator_vrm_set_voltage_sel,
3868c2ecf20Sopenharmony_ci	.get_voltage_sel	= rpmh_regulator_vrm_get_voltage_sel,
3878c2ecf20Sopenharmony_ci	.list_voltage		= regulator_list_voltage_linear_range,
3888c2ecf20Sopenharmony_ci	.set_mode		= rpmh_regulator_vrm_set_mode,
3898c2ecf20Sopenharmony_ci	.get_mode		= rpmh_regulator_vrm_get_mode,
3908c2ecf20Sopenharmony_ci	.set_bypass		= rpmh_regulator_vrm_set_bypass,
3918c2ecf20Sopenharmony_ci	.get_bypass		= rpmh_regulator_vrm_get_bypass,
3928c2ecf20Sopenharmony_ci};
3938c2ecf20Sopenharmony_ci
3948c2ecf20Sopenharmony_cistatic const struct regulator_ops rpmh_regulator_xob_ops = {
3958c2ecf20Sopenharmony_ci	.enable			= rpmh_regulator_enable,
3968c2ecf20Sopenharmony_ci	.disable		= rpmh_regulator_disable,
3978c2ecf20Sopenharmony_ci	.is_enabled		= rpmh_regulator_is_enabled,
3988c2ecf20Sopenharmony_ci};
3998c2ecf20Sopenharmony_ci
4008c2ecf20Sopenharmony_ci/**
4018c2ecf20Sopenharmony_ci * rpmh_regulator_init_vreg() - initialize all attributes of an rpmh-regulator
4028c2ecf20Sopenharmony_ci * @vreg:		Pointer to the individual rpmh-regulator resource
4038c2ecf20Sopenharmony_ci * @dev:			Pointer to the top level rpmh-regulator PMIC device
4048c2ecf20Sopenharmony_ci * @node:		Pointer to the individual rpmh-regulator resource
4058c2ecf20Sopenharmony_ci *			device node
4068c2ecf20Sopenharmony_ci * @pmic_id:		String used to identify the top level rpmh-regulator
4078c2ecf20Sopenharmony_ci *			PMIC device on the board
4088c2ecf20Sopenharmony_ci * @pmic_rpmh_data:	Pointer to a null-terminated array of rpmh-regulator
4098c2ecf20Sopenharmony_ci *			resources defined for the top level PMIC device
4108c2ecf20Sopenharmony_ci *
4118c2ecf20Sopenharmony_ci * Return: 0 on success, errno on failure
4128c2ecf20Sopenharmony_ci */
4138c2ecf20Sopenharmony_cistatic int rpmh_regulator_init_vreg(struct rpmh_vreg *vreg, struct device *dev,
4148c2ecf20Sopenharmony_ci			struct device_node *node, const char *pmic_id,
4158c2ecf20Sopenharmony_ci			const struct rpmh_vreg_init_data *pmic_rpmh_data)
4168c2ecf20Sopenharmony_ci{
4178c2ecf20Sopenharmony_ci	struct regulator_config reg_config = {};
4188c2ecf20Sopenharmony_ci	char rpmh_resource_name[20] = "";
4198c2ecf20Sopenharmony_ci	const struct rpmh_vreg_init_data *rpmh_data;
4208c2ecf20Sopenharmony_ci	struct regulator_init_data *init_data;
4218c2ecf20Sopenharmony_ci	struct regulator_dev *rdev;
4228c2ecf20Sopenharmony_ci	int ret;
4238c2ecf20Sopenharmony_ci
4248c2ecf20Sopenharmony_ci	vreg->dev = dev;
4258c2ecf20Sopenharmony_ci
4268c2ecf20Sopenharmony_ci	for (rpmh_data = pmic_rpmh_data; rpmh_data->name; rpmh_data++)
4278c2ecf20Sopenharmony_ci		if (of_node_name_eq(node, rpmh_data->name))
4288c2ecf20Sopenharmony_ci			break;
4298c2ecf20Sopenharmony_ci
4308c2ecf20Sopenharmony_ci	if (!rpmh_data->name) {
4318c2ecf20Sopenharmony_ci		dev_err(dev, "Unknown regulator %pOFn\n", node);
4328c2ecf20Sopenharmony_ci		return -EINVAL;
4338c2ecf20Sopenharmony_ci	}
4348c2ecf20Sopenharmony_ci
4358c2ecf20Sopenharmony_ci	scnprintf(rpmh_resource_name, sizeof(rpmh_resource_name),
4368c2ecf20Sopenharmony_ci		rpmh_data->resource_name, pmic_id);
4378c2ecf20Sopenharmony_ci
4388c2ecf20Sopenharmony_ci	vreg->addr = cmd_db_read_addr(rpmh_resource_name);
4398c2ecf20Sopenharmony_ci	if (!vreg->addr) {
4408c2ecf20Sopenharmony_ci		dev_err(dev, "%pOFn: could not find RPMh address for resource %s\n",
4418c2ecf20Sopenharmony_ci			node, rpmh_resource_name);
4428c2ecf20Sopenharmony_ci		return -ENODEV;
4438c2ecf20Sopenharmony_ci	}
4448c2ecf20Sopenharmony_ci
4458c2ecf20Sopenharmony_ci	vreg->rdesc.name = rpmh_data->name;
4468c2ecf20Sopenharmony_ci	vreg->rdesc.supply_name = rpmh_data->supply_name;
4478c2ecf20Sopenharmony_ci	vreg->hw_data = rpmh_data->hw_data;
4488c2ecf20Sopenharmony_ci
4498c2ecf20Sopenharmony_ci	vreg->enabled = -EINVAL;
4508c2ecf20Sopenharmony_ci	vreg->voltage_selector = -ENOTRECOVERABLE;
4518c2ecf20Sopenharmony_ci	vreg->mode = REGULATOR_MODE_INVALID;
4528c2ecf20Sopenharmony_ci
4538c2ecf20Sopenharmony_ci	if (rpmh_data->hw_data->n_voltages) {
4548c2ecf20Sopenharmony_ci		vreg->rdesc.linear_ranges = &rpmh_data->hw_data->voltage_range;
4558c2ecf20Sopenharmony_ci		vreg->rdesc.n_linear_ranges = 1;
4568c2ecf20Sopenharmony_ci		vreg->rdesc.n_voltages = rpmh_data->hw_data->n_voltages;
4578c2ecf20Sopenharmony_ci	}
4588c2ecf20Sopenharmony_ci
4598c2ecf20Sopenharmony_ci	vreg->always_wait_for_ack = of_property_read_bool(node,
4608c2ecf20Sopenharmony_ci						"qcom,always-wait-for-ack");
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_ci	vreg->rdesc.owner	= THIS_MODULE;
4638c2ecf20Sopenharmony_ci	vreg->rdesc.type	= REGULATOR_VOLTAGE;
4648c2ecf20Sopenharmony_ci	vreg->rdesc.ops		= vreg->hw_data->ops;
4658c2ecf20Sopenharmony_ci	vreg->rdesc.of_map_mode	= vreg->hw_data->of_map_mode;
4668c2ecf20Sopenharmony_ci
4678c2ecf20Sopenharmony_ci	init_data = of_get_regulator_init_data(dev, node, &vreg->rdesc);
4688c2ecf20Sopenharmony_ci	if (!init_data)
4698c2ecf20Sopenharmony_ci		return -ENOMEM;
4708c2ecf20Sopenharmony_ci
4718c2ecf20Sopenharmony_ci	if (rpmh_data->hw_data->regulator_type == XOB &&
4728c2ecf20Sopenharmony_ci	    init_data->constraints.min_uV &&
4738c2ecf20Sopenharmony_ci	    init_data->constraints.min_uV == init_data->constraints.max_uV) {
4748c2ecf20Sopenharmony_ci		vreg->rdesc.fixed_uV = init_data->constraints.min_uV;
4758c2ecf20Sopenharmony_ci		vreg->rdesc.n_voltages = 1;
4768c2ecf20Sopenharmony_ci	}
4778c2ecf20Sopenharmony_ci
4788c2ecf20Sopenharmony_ci	reg_config.dev		= dev;
4798c2ecf20Sopenharmony_ci	reg_config.init_data	= init_data;
4808c2ecf20Sopenharmony_ci	reg_config.of_node	= node;
4818c2ecf20Sopenharmony_ci	reg_config.driver_data	= vreg;
4828c2ecf20Sopenharmony_ci
4838c2ecf20Sopenharmony_ci	rdev = devm_regulator_register(dev, &vreg->rdesc, &reg_config);
4848c2ecf20Sopenharmony_ci	if (IS_ERR(rdev)) {
4858c2ecf20Sopenharmony_ci		ret = PTR_ERR(rdev);
4868c2ecf20Sopenharmony_ci		dev_err(dev, "%pOFn: devm_regulator_register() failed, ret=%d\n",
4878c2ecf20Sopenharmony_ci			node, ret);
4888c2ecf20Sopenharmony_ci		return ret;
4898c2ecf20Sopenharmony_ci	}
4908c2ecf20Sopenharmony_ci
4918c2ecf20Sopenharmony_ci	dev_dbg(dev, "%pOFn regulator registered for RPMh resource %s @ 0x%05X\n",
4928c2ecf20Sopenharmony_ci		node, rpmh_resource_name, vreg->addr);
4938c2ecf20Sopenharmony_ci
4948c2ecf20Sopenharmony_ci	return 0;
4958c2ecf20Sopenharmony_ci}
4968c2ecf20Sopenharmony_ci
4978c2ecf20Sopenharmony_cistatic const int pmic_mode_map_pmic4_ldo[REGULATOR_MODE_STANDBY + 1] = {
4988c2ecf20Sopenharmony_ci	[REGULATOR_MODE_INVALID] = -EINVAL,
4998c2ecf20Sopenharmony_ci	[REGULATOR_MODE_STANDBY] = PMIC4_LDO_MODE_RETENTION,
5008c2ecf20Sopenharmony_ci	[REGULATOR_MODE_IDLE]    = PMIC4_LDO_MODE_LPM,
5018c2ecf20Sopenharmony_ci	[REGULATOR_MODE_NORMAL]  = PMIC4_LDO_MODE_HPM,
5028c2ecf20Sopenharmony_ci	[REGULATOR_MODE_FAST]    = -EINVAL,
5038c2ecf20Sopenharmony_ci};
5048c2ecf20Sopenharmony_ci
5058c2ecf20Sopenharmony_cistatic const int pmic_mode_map_pmic5_ldo[REGULATOR_MODE_STANDBY + 1] = {
5068c2ecf20Sopenharmony_ci	[REGULATOR_MODE_INVALID] = -EINVAL,
5078c2ecf20Sopenharmony_ci	[REGULATOR_MODE_STANDBY] = PMIC5_LDO_MODE_RETENTION,
5088c2ecf20Sopenharmony_ci	[REGULATOR_MODE_IDLE]    = PMIC5_LDO_MODE_LPM,
5098c2ecf20Sopenharmony_ci	[REGULATOR_MODE_NORMAL]  = PMIC5_LDO_MODE_HPM,
5108c2ecf20Sopenharmony_ci	[REGULATOR_MODE_FAST]    = -EINVAL,
5118c2ecf20Sopenharmony_ci};
5128c2ecf20Sopenharmony_ci
5138c2ecf20Sopenharmony_cistatic unsigned int rpmh_regulator_pmic4_ldo_of_map_mode(unsigned int rpmh_mode)
5148c2ecf20Sopenharmony_ci{
5158c2ecf20Sopenharmony_ci	unsigned int mode;
5168c2ecf20Sopenharmony_ci
5178c2ecf20Sopenharmony_ci	switch (rpmh_mode) {
5188c2ecf20Sopenharmony_ci	case RPMH_REGULATOR_MODE_HPM:
5198c2ecf20Sopenharmony_ci		mode = REGULATOR_MODE_NORMAL;
5208c2ecf20Sopenharmony_ci		break;
5218c2ecf20Sopenharmony_ci	case RPMH_REGULATOR_MODE_LPM:
5228c2ecf20Sopenharmony_ci		mode = REGULATOR_MODE_IDLE;
5238c2ecf20Sopenharmony_ci		break;
5248c2ecf20Sopenharmony_ci	case RPMH_REGULATOR_MODE_RET:
5258c2ecf20Sopenharmony_ci		mode = REGULATOR_MODE_STANDBY;
5268c2ecf20Sopenharmony_ci		break;
5278c2ecf20Sopenharmony_ci	default:
5288c2ecf20Sopenharmony_ci		mode = REGULATOR_MODE_INVALID;
5298c2ecf20Sopenharmony_ci		break;
5308c2ecf20Sopenharmony_ci	}
5318c2ecf20Sopenharmony_ci
5328c2ecf20Sopenharmony_ci	return mode;
5338c2ecf20Sopenharmony_ci}
5348c2ecf20Sopenharmony_ci
5358c2ecf20Sopenharmony_cistatic const int pmic_mode_map_pmic4_smps[REGULATOR_MODE_STANDBY + 1] = {
5368c2ecf20Sopenharmony_ci	[REGULATOR_MODE_INVALID] = -EINVAL,
5378c2ecf20Sopenharmony_ci	[REGULATOR_MODE_STANDBY] = PMIC4_SMPS_MODE_RETENTION,
5388c2ecf20Sopenharmony_ci	[REGULATOR_MODE_IDLE]    = PMIC4_SMPS_MODE_PFM,
5398c2ecf20Sopenharmony_ci	[REGULATOR_MODE_NORMAL]  = PMIC4_SMPS_MODE_AUTO,
5408c2ecf20Sopenharmony_ci	[REGULATOR_MODE_FAST]    = PMIC4_SMPS_MODE_PWM,
5418c2ecf20Sopenharmony_ci};
5428c2ecf20Sopenharmony_ci
5438c2ecf20Sopenharmony_cistatic const int pmic_mode_map_pmic5_smps[REGULATOR_MODE_STANDBY + 1] = {
5448c2ecf20Sopenharmony_ci	[REGULATOR_MODE_INVALID] = -EINVAL,
5458c2ecf20Sopenharmony_ci	[REGULATOR_MODE_STANDBY] = PMIC5_SMPS_MODE_RETENTION,
5468c2ecf20Sopenharmony_ci	[REGULATOR_MODE_IDLE]    = PMIC5_SMPS_MODE_PFM,
5478c2ecf20Sopenharmony_ci	[REGULATOR_MODE_NORMAL]  = PMIC5_SMPS_MODE_AUTO,
5488c2ecf20Sopenharmony_ci	[REGULATOR_MODE_FAST]    = PMIC5_SMPS_MODE_PWM,
5498c2ecf20Sopenharmony_ci};
5508c2ecf20Sopenharmony_ci
5518c2ecf20Sopenharmony_cistatic unsigned int
5528c2ecf20Sopenharmony_cirpmh_regulator_pmic4_smps_of_map_mode(unsigned int rpmh_mode)
5538c2ecf20Sopenharmony_ci{
5548c2ecf20Sopenharmony_ci	unsigned int mode;
5558c2ecf20Sopenharmony_ci
5568c2ecf20Sopenharmony_ci	switch (rpmh_mode) {
5578c2ecf20Sopenharmony_ci	case RPMH_REGULATOR_MODE_HPM:
5588c2ecf20Sopenharmony_ci		mode = REGULATOR_MODE_FAST;
5598c2ecf20Sopenharmony_ci		break;
5608c2ecf20Sopenharmony_ci	case RPMH_REGULATOR_MODE_AUTO:
5618c2ecf20Sopenharmony_ci		mode = REGULATOR_MODE_NORMAL;
5628c2ecf20Sopenharmony_ci		break;
5638c2ecf20Sopenharmony_ci	case RPMH_REGULATOR_MODE_LPM:
5648c2ecf20Sopenharmony_ci		mode = REGULATOR_MODE_IDLE;
5658c2ecf20Sopenharmony_ci		break;
5668c2ecf20Sopenharmony_ci	case RPMH_REGULATOR_MODE_RET:
5678c2ecf20Sopenharmony_ci		mode = REGULATOR_MODE_STANDBY;
5688c2ecf20Sopenharmony_ci		break;
5698c2ecf20Sopenharmony_ci	default:
5708c2ecf20Sopenharmony_ci		mode = REGULATOR_MODE_INVALID;
5718c2ecf20Sopenharmony_ci		break;
5728c2ecf20Sopenharmony_ci	}
5738c2ecf20Sopenharmony_ci
5748c2ecf20Sopenharmony_ci	return mode;
5758c2ecf20Sopenharmony_ci}
5768c2ecf20Sopenharmony_ci
5778c2ecf20Sopenharmony_cistatic const int pmic_mode_map_pmic4_bob[REGULATOR_MODE_STANDBY + 1] = {
5788c2ecf20Sopenharmony_ci	[REGULATOR_MODE_INVALID] = -EINVAL,
5798c2ecf20Sopenharmony_ci	[REGULATOR_MODE_STANDBY] = -EINVAL,
5808c2ecf20Sopenharmony_ci	[REGULATOR_MODE_IDLE]    = PMIC4_BOB_MODE_PFM,
5818c2ecf20Sopenharmony_ci	[REGULATOR_MODE_NORMAL]  = PMIC4_BOB_MODE_AUTO,
5828c2ecf20Sopenharmony_ci	[REGULATOR_MODE_FAST]    = PMIC4_BOB_MODE_PWM,
5838c2ecf20Sopenharmony_ci};
5848c2ecf20Sopenharmony_ci
5858c2ecf20Sopenharmony_cistatic const int pmic_mode_map_pmic5_bob[REGULATOR_MODE_STANDBY + 1] = {
5868c2ecf20Sopenharmony_ci	[REGULATOR_MODE_INVALID] = -EINVAL,
5878c2ecf20Sopenharmony_ci	[REGULATOR_MODE_STANDBY] = -EINVAL,
5888c2ecf20Sopenharmony_ci	[REGULATOR_MODE_IDLE]    = PMIC5_BOB_MODE_PFM,
5898c2ecf20Sopenharmony_ci	[REGULATOR_MODE_NORMAL]  = PMIC5_BOB_MODE_AUTO,
5908c2ecf20Sopenharmony_ci	[REGULATOR_MODE_FAST]    = PMIC5_BOB_MODE_PWM,
5918c2ecf20Sopenharmony_ci};
5928c2ecf20Sopenharmony_ci
5938c2ecf20Sopenharmony_cistatic unsigned int rpmh_regulator_pmic4_bob_of_map_mode(unsigned int rpmh_mode)
5948c2ecf20Sopenharmony_ci{
5958c2ecf20Sopenharmony_ci	unsigned int mode;
5968c2ecf20Sopenharmony_ci
5978c2ecf20Sopenharmony_ci	switch (rpmh_mode) {
5988c2ecf20Sopenharmony_ci	case RPMH_REGULATOR_MODE_HPM:
5998c2ecf20Sopenharmony_ci		mode = REGULATOR_MODE_FAST;
6008c2ecf20Sopenharmony_ci		break;
6018c2ecf20Sopenharmony_ci	case RPMH_REGULATOR_MODE_AUTO:
6028c2ecf20Sopenharmony_ci		mode = REGULATOR_MODE_NORMAL;
6038c2ecf20Sopenharmony_ci		break;
6048c2ecf20Sopenharmony_ci	case RPMH_REGULATOR_MODE_LPM:
6058c2ecf20Sopenharmony_ci		mode = REGULATOR_MODE_IDLE;
6068c2ecf20Sopenharmony_ci		break;
6078c2ecf20Sopenharmony_ci	default:
6088c2ecf20Sopenharmony_ci		mode = REGULATOR_MODE_INVALID;
6098c2ecf20Sopenharmony_ci		break;
6108c2ecf20Sopenharmony_ci	}
6118c2ecf20Sopenharmony_ci
6128c2ecf20Sopenharmony_ci	return mode;
6138c2ecf20Sopenharmony_ci}
6148c2ecf20Sopenharmony_ci
6158c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_hw_data pmic4_pldo = {
6168c2ecf20Sopenharmony_ci	.regulator_type = VRM,
6178c2ecf20Sopenharmony_ci	.ops = &rpmh_regulator_vrm_drms_ops,
6188c2ecf20Sopenharmony_ci	.voltage_range = REGULATOR_LINEAR_RANGE(1664000, 0, 255, 8000),
6198c2ecf20Sopenharmony_ci	.n_voltages = 256,
6208c2ecf20Sopenharmony_ci	.hpm_min_load_uA = 10000,
6218c2ecf20Sopenharmony_ci	.pmic_mode_map = pmic_mode_map_pmic4_ldo,
6228c2ecf20Sopenharmony_ci	.of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
6238c2ecf20Sopenharmony_ci};
6248c2ecf20Sopenharmony_ci
6258c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_hw_data pmic4_pldo_lv = {
6268c2ecf20Sopenharmony_ci	.regulator_type = VRM,
6278c2ecf20Sopenharmony_ci	.ops = &rpmh_regulator_vrm_drms_ops,
6288c2ecf20Sopenharmony_ci	.voltage_range = REGULATOR_LINEAR_RANGE(1256000, 0, 127, 8000),
6298c2ecf20Sopenharmony_ci	.n_voltages = 128,
6308c2ecf20Sopenharmony_ci	.hpm_min_load_uA = 10000,
6318c2ecf20Sopenharmony_ci	.pmic_mode_map = pmic_mode_map_pmic4_ldo,
6328c2ecf20Sopenharmony_ci	.of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
6338c2ecf20Sopenharmony_ci};
6348c2ecf20Sopenharmony_ci
6358c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_hw_data pmic4_nldo = {
6368c2ecf20Sopenharmony_ci	.regulator_type = VRM,
6378c2ecf20Sopenharmony_ci	.ops = &rpmh_regulator_vrm_drms_ops,
6388c2ecf20Sopenharmony_ci	.voltage_range = REGULATOR_LINEAR_RANGE(312000, 0, 127, 8000),
6398c2ecf20Sopenharmony_ci	.n_voltages = 128,
6408c2ecf20Sopenharmony_ci	.hpm_min_load_uA = 30000,
6418c2ecf20Sopenharmony_ci	.pmic_mode_map = pmic_mode_map_pmic4_ldo,
6428c2ecf20Sopenharmony_ci	.of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
6438c2ecf20Sopenharmony_ci};
6448c2ecf20Sopenharmony_ci
6458c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_hw_data pmic4_hfsmps3 = {
6468c2ecf20Sopenharmony_ci	.regulator_type = VRM,
6478c2ecf20Sopenharmony_ci	.ops = &rpmh_regulator_vrm_ops,
6488c2ecf20Sopenharmony_ci	.voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
6498c2ecf20Sopenharmony_ci	.n_voltages = 216,
6508c2ecf20Sopenharmony_ci	.pmic_mode_map = pmic_mode_map_pmic4_smps,
6518c2ecf20Sopenharmony_ci	.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
6528c2ecf20Sopenharmony_ci};
6538c2ecf20Sopenharmony_ci
6548c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_hw_data pmic4_ftsmps426 = {
6558c2ecf20Sopenharmony_ci	.regulator_type = VRM,
6568c2ecf20Sopenharmony_ci	.ops = &rpmh_regulator_vrm_ops,
6578c2ecf20Sopenharmony_ci	.voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 258, 4000),
6588c2ecf20Sopenharmony_ci	.n_voltages = 259,
6598c2ecf20Sopenharmony_ci	.pmic_mode_map = pmic_mode_map_pmic4_smps,
6608c2ecf20Sopenharmony_ci	.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
6618c2ecf20Sopenharmony_ci};
6628c2ecf20Sopenharmony_ci
6638c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_hw_data pmic4_bob = {
6648c2ecf20Sopenharmony_ci	.regulator_type = VRM,
6658c2ecf20Sopenharmony_ci	.ops = &rpmh_regulator_vrm_bypass_ops,
6668c2ecf20Sopenharmony_ci	.voltage_range = REGULATOR_LINEAR_RANGE(1824000, 0, 83, 32000),
6678c2ecf20Sopenharmony_ci	.n_voltages = 84,
6688c2ecf20Sopenharmony_ci	.pmic_mode_map = pmic_mode_map_pmic4_bob,
6698c2ecf20Sopenharmony_ci	.of_map_mode = rpmh_regulator_pmic4_bob_of_map_mode,
6708c2ecf20Sopenharmony_ci};
6718c2ecf20Sopenharmony_ci
6728c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_hw_data pmic4_lvs = {
6738c2ecf20Sopenharmony_ci	.regulator_type = XOB,
6748c2ecf20Sopenharmony_ci	.ops = &rpmh_regulator_xob_ops,
6758c2ecf20Sopenharmony_ci	/* LVS hardware does not support voltage or mode configuration. */
6768c2ecf20Sopenharmony_ci};
6778c2ecf20Sopenharmony_ci
6788c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_hw_data pmic5_pldo = {
6798c2ecf20Sopenharmony_ci	.regulator_type = VRM,
6808c2ecf20Sopenharmony_ci	.ops = &rpmh_regulator_vrm_drms_ops,
6818c2ecf20Sopenharmony_ci	.voltage_range = REGULATOR_LINEAR_RANGE(1504000, 0, 255, 8000),
6828c2ecf20Sopenharmony_ci	.n_voltages = 256,
6838c2ecf20Sopenharmony_ci	.hpm_min_load_uA = 10000,
6848c2ecf20Sopenharmony_ci	.pmic_mode_map = pmic_mode_map_pmic5_ldo,
6858c2ecf20Sopenharmony_ci	.of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
6868c2ecf20Sopenharmony_ci};
6878c2ecf20Sopenharmony_ci
6888c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_hw_data pmic5_pldo_lv = {
6898c2ecf20Sopenharmony_ci	.regulator_type = VRM,
6908c2ecf20Sopenharmony_ci	.ops = &rpmh_regulator_vrm_drms_ops,
6918c2ecf20Sopenharmony_ci	.voltage_range = REGULATOR_LINEAR_RANGE(1504000, 0, 62, 8000),
6928c2ecf20Sopenharmony_ci	.n_voltages = 63,
6938c2ecf20Sopenharmony_ci	.hpm_min_load_uA = 10000,
6948c2ecf20Sopenharmony_ci	.pmic_mode_map = pmic_mode_map_pmic5_ldo,
6958c2ecf20Sopenharmony_ci	.of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
6968c2ecf20Sopenharmony_ci};
6978c2ecf20Sopenharmony_ci
6988c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_hw_data pmic5_nldo = {
6998c2ecf20Sopenharmony_ci	.regulator_type = VRM,
7008c2ecf20Sopenharmony_ci	.ops = &rpmh_regulator_vrm_drms_ops,
7018c2ecf20Sopenharmony_ci	.voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 123, 8000),
7028c2ecf20Sopenharmony_ci	.n_voltages = 124,
7038c2ecf20Sopenharmony_ci	.hpm_min_load_uA = 30000,
7048c2ecf20Sopenharmony_ci	.pmic_mode_map = pmic_mode_map_pmic5_ldo,
7058c2ecf20Sopenharmony_ci	.of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
7068c2ecf20Sopenharmony_ci};
7078c2ecf20Sopenharmony_ci
7088c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_hw_data pmic5_hfsmps510 = {
7098c2ecf20Sopenharmony_ci	.regulator_type = VRM,
7108c2ecf20Sopenharmony_ci	.ops = &rpmh_regulator_vrm_ops,
7118c2ecf20Sopenharmony_ci	.voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
7128c2ecf20Sopenharmony_ci	.n_voltages = 216,
7138c2ecf20Sopenharmony_ci	.pmic_mode_map = pmic_mode_map_pmic5_smps,
7148c2ecf20Sopenharmony_ci	.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
7158c2ecf20Sopenharmony_ci};
7168c2ecf20Sopenharmony_ci
7178c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_hw_data pmic5_ftsmps510 = {
7188c2ecf20Sopenharmony_ci	.regulator_type = VRM,
7198c2ecf20Sopenharmony_ci	.ops = &rpmh_regulator_vrm_ops,
7208c2ecf20Sopenharmony_ci	.voltage_range = REGULATOR_LINEAR_RANGE(300000, 0, 263, 4000),
7218c2ecf20Sopenharmony_ci	.n_voltages = 264,
7228c2ecf20Sopenharmony_ci	.pmic_mode_map = pmic_mode_map_pmic5_smps,
7238c2ecf20Sopenharmony_ci	.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
7248c2ecf20Sopenharmony_ci};
7258c2ecf20Sopenharmony_ci
7268c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_hw_data pmic5_hfsmps515 = {
7278c2ecf20Sopenharmony_ci	.regulator_type = VRM,
7288c2ecf20Sopenharmony_ci	.ops = &rpmh_regulator_vrm_ops,
7298c2ecf20Sopenharmony_ci	.voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 235, 16000),
7308c2ecf20Sopenharmony_ci	.n_voltages = 236,
7318c2ecf20Sopenharmony_ci	.pmic_mode_map = pmic_mode_map_pmic5_smps,
7328c2ecf20Sopenharmony_ci	.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
7338c2ecf20Sopenharmony_ci};
7348c2ecf20Sopenharmony_ci
7358c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_hw_data pmic5_hfsmps515_1 = {
7368c2ecf20Sopenharmony_ci	.regulator_type = VRM,
7378c2ecf20Sopenharmony_ci	.ops = &rpmh_regulator_vrm_ops,
7388c2ecf20Sopenharmony_ci	.voltage_range = REGULATOR_LINEAR_RANGE(900000, 0, 4, 16000),
7398c2ecf20Sopenharmony_ci	.n_voltages = 5,
7408c2ecf20Sopenharmony_ci	.pmic_mode_map = pmic_mode_map_pmic5_smps,
7418c2ecf20Sopenharmony_ci	.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
7428c2ecf20Sopenharmony_ci};
7438c2ecf20Sopenharmony_ci
7448c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_hw_data pmic5_bob = {
7458c2ecf20Sopenharmony_ci	.regulator_type = VRM,
7468c2ecf20Sopenharmony_ci	.ops = &rpmh_regulator_vrm_bypass_ops,
7478c2ecf20Sopenharmony_ci	.voltage_range = REGULATOR_LINEAR_RANGE(3000000, 0, 31, 32000),
7488c2ecf20Sopenharmony_ci	.n_voltages = 32,
7498c2ecf20Sopenharmony_ci	.pmic_mode_map = pmic_mode_map_pmic5_bob,
7508c2ecf20Sopenharmony_ci	.of_map_mode = rpmh_regulator_pmic4_bob_of_map_mode,
7518c2ecf20Sopenharmony_ci};
7528c2ecf20Sopenharmony_ci
7538c2ecf20Sopenharmony_ci#define RPMH_VREG(_name, _resource_name, _hw_data, _supply_name) \
7548c2ecf20Sopenharmony_ci{ \
7558c2ecf20Sopenharmony_ci	.name		= _name, \
7568c2ecf20Sopenharmony_ci	.resource_name	= _resource_name, \
7578c2ecf20Sopenharmony_ci	.hw_data	= _hw_data, \
7588c2ecf20Sopenharmony_ci	.supply_name	= _supply_name, \
7598c2ecf20Sopenharmony_ci}
7608c2ecf20Sopenharmony_ci
7618c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_init_data pm8998_vreg_data[] = {
7628c2ecf20Sopenharmony_ci	RPMH_VREG("smps1",  "smp%s1",  &pmic4_ftsmps426, "vdd-s1"),
7638c2ecf20Sopenharmony_ci	RPMH_VREG("smps2",  "smp%s2",  &pmic4_ftsmps426, "vdd-s2"),
7648c2ecf20Sopenharmony_ci	RPMH_VREG("smps3",  "smp%s3",  &pmic4_hfsmps3,   "vdd-s3"),
7658c2ecf20Sopenharmony_ci	RPMH_VREG("smps4",  "smp%s4",  &pmic4_hfsmps3,   "vdd-s4"),
7668c2ecf20Sopenharmony_ci	RPMH_VREG("smps5",  "smp%s5",  &pmic4_hfsmps3,   "vdd-s5"),
7678c2ecf20Sopenharmony_ci	RPMH_VREG("smps6",  "smp%s6",  &pmic4_ftsmps426, "vdd-s6"),
7688c2ecf20Sopenharmony_ci	RPMH_VREG("smps7",  "smp%s7",  &pmic4_ftsmps426, "vdd-s7"),
7698c2ecf20Sopenharmony_ci	RPMH_VREG("smps8",  "smp%s8",  &pmic4_ftsmps426, "vdd-s8"),
7708c2ecf20Sopenharmony_ci	RPMH_VREG("smps9",  "smp%s9",  &pmic4_ftsmps426, "vdd-s9"),
7718c2ecf20Sopenharmony_ci	RPMH_VREG("smps10", "smp%s10", &pmic4_ftsmps426, "vdd-s10"),
7728c2ecf20Sopenharmony_ci	RPMH_VREG("smps11", "smp%s11", &pmic4_ftsmps426, "vdd-s11"),
7738c2ecf20Sopenharmony_ci	RPMH_VREG("smps12", "smp%s12", &pmic4_ftsmps426, "vdd-s12"),
7748c2ecf20Sopenharmony_ci	RPMH_VREG("smps13", "smp%s13", &pmic4_ftsmps426, "vdd-s13"),
7758c2ecf20Sopenharmony_ci	RPMH_VREG("ldo1",   "ldo%s1",  &pmic4_nldo,      "vdd-l1-l27"),
7768c2ecf20Sopenharmony_ci	RPMH_VREG("ldo2",   "ldo%s2",  &pmic4_nldo,      "vdd-l2-l8-l17"),
7778c2ecf20Sopenharmony_ci	RPMH_VREG("ldo3",   "ldo%s3",  &pmic4_nldo,      "vdd-l3-l11"),
7788c2ecf20Sopenharmony_ci	RPMH_VREG("ldo4",   "ldo%s4",  &pmic4_nldo,      "vdd-l4-l5"),
7798c2ecf20Sopenharmony_ci	RPMH_VREG("ldo5",   "ldo%s5",  &pmic4_nldo,      "vdd-l4-l5"),
7808c2ecf20Sopenharmony_ci	RPMH_VREG("ldo6",   "ldo%s6",  &pmic4_pldo,      "vdd-l6"),
7818c2ecf20Sopenharmony_ci	RPMH_VREG("ldo7",   "ldo%s7",  &pmic4_pldo_lv,   "vdd-l7-l12-l14-l15"),
7828c2ecf20Sopenharmony_ci	RPMH_VREG("ldo8",   "ldo%s8",  &pmic4_nldo,      "vdd-l2-l8-l17"),
7838c2ecf20Sopenharmony_ci	RPMH_VREG("ldo9",   "ldo%s9",  &pmic4_pldo,      "vdd-l9"),
7848c2ecf20Sopenharmony_ci	RPMH_VREG("ldo10",  "ldo%s10", &pmic4_pldo,      "vdd-l10-l23-l25"),
7858c2ecf20Sopenharmony_ci	RPMH_VREG("ldo11",  "ldo%s11", &pmic4_nldo,      "vdd-l3-l11"),
7868c2ecf20Sopenharmony_ci	RPMH_VREG("ldo12",  "ldo%s12", &pmic4_pldo_lv,   "vdd-l7-l12-l14-l15"),
7878c2ecf20Sopenharmony_ci	RPMH_VREG("ldo13",  "ldo%s13", &pmic4_pldo,      "vdd-l13-l19-l21"),
7888c2ecf20Sopenharmony_ci	RPMH_VREG("ldo14",  "ldo%s14", &pmic4_pldo_lv,   "vdd-l7-l12-l14-l15"),
7898c2ecf20Sopenharmony_ci	RPMH_VREG("ldo15",  "ldo%s15", &pmic4_pldo_lv,   "vdd-l7-l12-l14-l15"),
7908c2ecf20Sopenharmony_ci	RPMH_VREG("ldo16",  "ldo%s16", &pmic4_pldo,      "vdd-l16-l28"),
7918c2ecf20Sopenharmony_ci	RPMH_VREG("ldo17",  "ldo%s17", &pmic4_nldo,      "vdd-l2-l8-l17"),
7928c2ecf20Sopenharmony_ci	RPMH_VREG("ldo18",  "ldo%s18", &pmic4_pldo,      "vdd-l18-l22"),
7938c2ecf20Sopenharmony_ci	RPMH_VREG("ldo19",  "ldo%s19", &pmic4_pldo,      "vdd-l13-l19-l21"),
7948c2ecf20Sopenharmony_ci	RPMH_VREG("ldo20",  "ldo%s20", &pmic4_pldo,      "vdd-l20-l24"),
7958c2ecf20Sopenharmony_ci	RPMH_VREG("ldo21",  "ldo%s21", &pmic4_pldo,      "vdd-l13-l19-l21"),
7968c2ecf20Sopenharmony_ci	RPMH_VREG("ldo22",  "ldo%s22", &pmic4_pldo,      "vdd-l18-l22"),
7978c2ecf20Sopenharmony_ci	RPMH_VREG("ldo23",  "ldo%s23", &pmic4_pldo,      "vdd-l10-l23-l25"),
7988c2ecf20Sopenharmony_ci	RPMH_VREG("ldo24",  "ldo%s24", &pmic4_pldo,      "vdd-l20-l24"),
7998c2ecf20Sopenharmony_ci	RPMH_VREG("ldo25",  "ldo%s25", &pmic4_pldo,      "vdd-l10-l23-l25"),
8008c2ecf20Sopenharmony_ci	RPMH_VREG("ldo26",  "ldo%s26", &pmic4_nldo,      "vdd-l26"),
8018c2ecf20Sopenharmony_ci	RPMH_VREG("ldo27",  "ldo%s27", &pmic4_nldo,      "vdd-l1-l27"),
8028c2ecf20Sopenharmony_ci	RPMH_VREG("ldo28",  "ldo%s28", &pmic4_pldo,      "vdd-l16-l28"),
8038c2ecf20Sopenharmony_ci	RPMH_VREG("lvs1",   "vs%s1",   &pmic4_lvs,       "vin-lvs-1-2"),
8048c2ecf20Sopenharmony_ci	RPMH_VREG("lvs2",   "vs%s2",   &pmic4_lvs,       "vin-lvs-1-2"),
8058c2ecf20Sopenharmony_ci	{},
8068c2ecf20Sopenharmony_ci};
8078c2ecf20Sopenharmony_ci
8088c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_init_data pmi8998_vreg_data[] = {
8098c2ecf20Sopenharmony_ci	RPMH_VREG("bob",    "bob%s1",  &pmic4_bob,       "vdd-bob"),
8108c2ecf20Sopenharmony_ci	{},
8118c2ecf20Sopenharmony_ci};
8128c2ecf20Sopenharmony_ci
8138c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_init_data pm8005_vreg_data[] = {
8148c2ecf20Sopenharmony_ci	RPMH_VREG("smps1",  "smp%s1",  &pmic4_ftsmps426, "vdd-s1"),
8158c2ecf20Sopenharmony_ci	RPMH_VREG("smps2",  "smp%s2",  &pmic4_ftsmps426, "vdd-s2"),
8168c2ecf20Sopenharmony_ci	RPMH_VREG("smps3",  "smp%s3",  &pmic4_ftsmps426, "vdd-s3"),
8178c2ecf20Sopenharmony_ci	RPMH_VREG("smps4",  "smp%s4",  &pmic4_ftsmps426, "vdd-s4"),
8188c2ecf20Sopenharmony_ci	{},
8198c2ecf20Sopenharmony_ci};
8208c2ecf20Sopenharmony_ci
8218c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_init_data pm8150_vreg_data[] = {
8228c2ecf20Sopenharmony_ci	RPMH_VREG("smps1",  "smp%s1",  &pmic5_ftsmps510, "vdd-s1"),
8238c2ecf20Sopenharmony_ci	RPMH_VREG("smps2",  "smp%s2",  &pmic5_ftsmps510, "vdd-s2"),
8248c2ecf20Sopenharmony_ci	RPMH_VREG("smps3",  "smp%s3",  &pmic5_ftsmps510, "vdd-s3"),
8258c2ecf20Sopenharmony_ci	RPMH_VREG("smps4",  "smp%s4",  &pmic5_hfsmps510,   "vdd-s4"),
8268c2ecf20Sopenharmony_ci	RPMH_VREG("smps5",  "smp%s5",  &pmic5_hfsmps510,   "vdd-s5"),
8278c2ecf20Sopenharmony_ci	RPMH_VREG("smps6",  "smp%s6",  &pmic5_ftsmps510, "vdd-s6"),
8288c2ecf20Sopenharmony_ci	RPMH_VREG("smps7",  "smp%s7",  &pmic5_ftsmps510, "vdd-s7"),
8298c2ecf20Sopenharmony_ci	RPMH_VREG("smps8",  "smp%s8",  &pmic5_ftsmps510, "vdd-s8"),
8308c2ecf20Sopenharmony_ci	RPMH_VREG("smps9",  "smp%s9",  &pmic5_ftsmps510, "vdd-s9"),
8318c2ecf20Sopenharmony_ci	RPMH_VREG("smps10", "smp%s10", &pmic5_ftsmps510, "vdd-s10"),
8328c2ecf20Sopenharmony_ci	RPMH_VREG("ldo1",   "ldo%s1",  &pmic5_nldo,      "vdd-l1-l8-l11"),
8338c2ecf20Sopenharmony_ci	RPMH_VREG("ldo2",   "ldo%s2",  &pmic5_pldo,      "vdd-l2-l10"),
8348c2ecf20Sopenharmony_ci	RPMH_VREG("ldo3",   "ldo%s3",  &pmic5_nldo,      "vdd-l3-l4-l5-l18"),
8358c2ecf20Sopenharmony_ci	RPMH_VREG("ldo4",   "ldo%s4",  &pmic5_nldo,      "vdd-l3-l4-l5-l18"),
8368c2ecf20Sopenharmony_ci	RPMH_VREG("ldo5",   "ldo%s5",  &pmic5_nldo,      "vdd-l3-l4-l5-l18"),
8378c2ecf20Sopenharmony_ci	RPMH_VREG("ldo6",   "ldo%s6",  &pmic5_nldo,      "vdd-l6-l9"),
8388c2ecf20Sopenharmony_ci	RPMH_VREG("ldo7",   "ldo%s7",  &pmic5_pldo,      "vdd-l7-l12-l14-l15"),
8398c2ecf20Sopenharmony_ci	RPMH_VREG("ldo8",   "ldo%s8",  &pmic5_nldo,      "vdd-l1-l8-l11"),
8408c2ecf20Sopenharmony_ci	RPMH_VREG("ldo9",   "ldo%s9",  &pmic5_nldo,      "vdd-l6-l9"),
8418c2ecf20Sopenharmony_ci	RPMH_VREG("ldo10",  "ldo%s10", &pmic5_pldo,      "vdd-l2-l10"),
8428c2ecf20Sopenharmony_ci	RPMH_VREG("ldo11",  "ldo%s11", &pmic5_nldo,      "vdd-l1-l8-l11"),
8438c2ecf20Sopenharmony_ci	RPMH_VREG("ldo12",  "ldo%s12", &pmic5_pldo_lv,   "vdd-l7-l12-l14-l15"),
8448c2ecf20Sopenharmony_ci	RPMH_VREG("ldo13",  "ldo%s13", &pmic5_pldo,      "vdd-l13-l16-l17"),
8458c2ecf20Sopenharmony_ci	RPMH_VREG("ldo14",  "ldo%s14", &pmic5_pldo_lv,   "vdd-l7-l12-l14-l15"),
8468c2ecf20Sopenharmony_ci	RPMH_VREG("ldo15",  "ldo%s15", &pmic5_pldo_lv,   "vdd-l7-l12-l14-l15"),
8478c2ecf20Sopenharmony_ci	RPMH_VREG("ldo16",  "ldo%s16", &pmic5_pldo,      "vdd-l13-l16-l17"),
8488c2ecf20Sopenharmony_ci	RPMH_VREG("ldo17",  "ldo%s17", &pmic5_pldo,      "vdd-l13-l16-l17"),
8498c2ecf20Sopenharmony_ci	RPMH_VREG("ldo18",  "ldo%s18", &pmic5_nldo,      "vdd-l3-l4-l5-l18"),
8508c2ecf20Sopenharmony_ci	{},
8518c2ecf20Sopenharmony_ci};
8528c2ecf20Sopenharmony_ci
8538c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_init_data pm8150l_vreg_data[] = {
8548c2ecf20Sopenharmony_ci	RPMH_VREG("smps1",  "smp%s1",  &pmic5_ftsmps510, "vdd-s1"),
8558c2ecf20Sopenharmony_ci	RPMH_VREG("smps2",  "smp%s2",  &pmic5_ftsmps510, "vdd-s2"),
8568c2ecf20Sopenharmony_ci	RPMH_VREG("smps3",  "smp%s3",  &pmic5_ftsmps510, "vdd-s3"),
8578c2ecf20Sopenharmony_ci	RPMH_VREG("smps4",  "smp%s4",  &pmic5_ftsmps510, "vdd-s4"),
8588c2ecf20Sopenharmony_ci	RPMH_VREG("smps5",  "smp%s5",  &pmic5_ftsmps510, "vdd-s5"),
8598c2ecf20Sopenharmony_ci	RPMH_VREG("smps6",  "smp%s6",  &pmic5_ftsmps510, "vdd-s6"),
8608c2ecf20Sopenharmony_ci	RPMH_VREG("smps7",  "smp%s7",  &pmic5_ftsmps510, "vdd-s7"),
8618c2ecf20Sopenharmony_ci	RPMH_VREG("smps8",  "smp%s8",  &pmic5_hfsmps510, "vdd-s8"),
8628c2ecf20Sopenharmony_ci	RPMH_VREG("ldo1",   "ldo%s1",  &pmic5_pldo_lv,   "vdd-l1-l8"),
8638c2ecf20Sopenharmony_ci	RPMH_VREG("ldo2",   "ldo%s2",  &pmic5_nldo,      "vdd-l2-l3"),
8648c2ecf20Sopenharmony_ci	RPMH_VREG("ldo3",   "ldo%s3",  &pmic5_nldo,      "vdd-l2-l3"),
8658c2ecf20Sopenharmony_ci	RPMH_VREG("ldo4",   "ldo%s4",  &pmic5_pldo,      "vdd-l4-l5-l6"),
8668c2ecf20Sopenharmony_ci	RPMH_VREG("ldo5",   "ldo%s5",  &pmic5_pldo,      "vdd-l4-l5-l6"),
8678c2ecf20Sopenharmony_ci	RPMH_VREG("ldo6",   "ldo%s6",  &pmic5_pldo,      "vdd-l4-l5-l6"),
8688c2ecf20Sopenharmony_ci	RPMH_VREG("ldo7",   "ldo%s7",  &pmic5_pldo,      "vdd-l7-l11"),
8698c2ecf20Sopenharmony_ci	RPMH_VREG("ldo8",   "ldo%s8",  &pmic5_pldo_lv,   "vdd-l1-l8"),
8708c2ecf20Sopenharmony_ci	RPMH_VREG("ldo9",   "ldo%s9",  &pmic5_pldo,      "vdd-l9-l10"),
8718c2ecf20Sopenharmony_ci	RPMH_VREG("ldo10",  "ldo%s10", &pmic5_pldo,      "vdd-l9-l10"),
8728c2ecf20Sopenharmony_ci	RPMH_VREG("ldo11",  "ldo%s11", &pmic5_pldo,      "vdd-l7-l11"),
8738c2ecf20Sopenharmony_ci	RPMH_VREG("bob",    "bob%s1",  &pmic5_bob,       "vdd-bob"),
8748c2ecf20Sopenharmony_ci	{},
8758c2ecf20Sopenharmony_ci};
8768c2ecf20Sopenharmony_ci
8778c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_init_data pm8009_vreg_data[] = {
8788c2ecf20Sopenharmony_ci	RPMH_VREG("smps1",  "smp%s1",  &pmic5_hfsmps510, "vdd-s1"),
8798c2ecf20Sopenharmony_ci	RPMH_VREG("smps2",  "smp%s2",  &pmic5_hfsmps515, "vdd-s2"),
8808c2ecf20Sopenharmony_ci	RPMH_VREG("ldo1",   "ldo%s1",  &pmic5_nldo,      "vdd-l1"),
8818c2ecf20Sopenharmony_ci	RPMH_VREG("ldo2",   "ldo%s2",  &pmic5_nldo,      "vdd-l2"),
8828c2ecf20Sopenharmony_ci	RPMH_VREG("ldo3",   "ldo%s3",  &pmic5_nldo,      "vdd-l3"),
8838c2ecf20Sopenharmony_ci	RPMH_VREG("ldo4",   "ldo%s4",  &pmic5_nldo,      "vdd-l4"),
8848c2ecf20Sopenharmony_ci	RPMH_VREG("ldo5",   "ldo%s5",  &pmic5_pldo,      "vdd-l5-l6"),
8858c2ecf20Sopenharmony_ci	RPMH_VREG("ldo6",   "ldo%s6",  &pmic5_pldo,      "vdd-l5-l6"),
8868c2ecf20Sopenharmony_ci	RPMH_VREG("ldo7",   "ldo%s7",  &pmic5_pldo_lv,   "vdd-l7"),
8878c2ecf20Sopenharmony_ci	{},
8888c2ecf20Sopenharmony_ci};
8898c2ecf20Sopenharmony_ci
8908c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_init_data pm8009_1_vreg_data[] = {
8918c2ecf20Sopenharmony_ci	RPMH_VREG("smps1",  "smp%s1",  &pmic5_hfsmps510, "vdd-s1"),
8928c2ecf20Sopenharmony_ci	RPMH_VREG("smps2",  "smp%s2",  &pmic5_hfsmps515_1, "vdd-s2"),
8938c2ecf20Sopenharmony_ci	RPMH_VREG("ldo1",   "ldo%s1",  &pmic5_nldo,      "vdd-l1"),
8948c2ecf20Sopenharmony_ci	RPMH_VREG("ldo2",   "ldo%s2",  &pmic5_nldo,      "vdd-l2"),
8958c2ecf20Sopenharmony_ci	RPMH_VREG("ldo3",   "ldo%s3",  &pmic5_nldo,      "vdd-l3"),
8968c2ecf20Sopenharmony_ci	RPMH_VREG("ldo4",   "ldo%s4",  &pmic5_nldo,      "vdd-l4"),
8978c2ecf20Sopenharmony_ci	RPMH_VREG("ldo5",   "ldo%s5",  &pmic5_pldo,      "vdd-l5-l6"),
8988c2ecf20Sopenharmony_ci	RPMH_VREG("ldo6",   "ldo%s6",  &pmic5_pldo,      "vdd-l5-l6"),
8998c2ecf20Sopenharmony_ci	RPMH_VREG("ldo7",   "ldo%s6",  &pmic5_pldo_lv,   "vdd-l7"),
9008c2ecf20Sopenharmony_ci	{},
9018c2ecf20Sopenharmony_ci};
9028c2ecf20Sopenharmony_ci
9038c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_init_data pm6150_vreg_data[] = {
9048c2ecf20Sopenharmony_ci	RPMH_VREG("smps1",  "smp%s1",  &pmic5_ftsmps510, "vdd-s1"),
9058c2ecf20Sopenharmony_ci	RPMH_VREG("smps2",  "smp%s2",  &pmic5_ftsmps510, "vdd-s2"),
9068c2ecf20Sopenharmony_ci	RPMH_VREG("smps3",  "smp%s3",  &pmic5_ftsmps510, "vdd-s3"),
9078c2ecf20Sopenharmony_ci	RPMH_VREG("smps4",  "smp%s4",  &pmic5_hfsmps510, "vdd-s4"),
9088c2ecf20Sopenharmony_ci	RPMH_VREG("smps5",  "smp%s5",  &pmic5_hfsmps510, "vdd-s5"),
9098c2ecf20Sopenharmony_ci	RPMH_VREG("ldo1",   "ldo%s1",  &pmic5_nldo,      "vdd-l1"),
9108c2ecf20Sopenharmony_ci	RPMH_VREG("ldo2",   "ldo%s2",  &pmic5_nldo,      "vdd-l2-l3"),
9118c2ecf20Sopenharmony_ci	RPMH_VREG("ldo3",   "ldo%s3",  &pmic5_nldo,      "vdd-l2-l3"),
9128c2ecf20Sopenharmony_ci	RPMH_VREG("ldo4",   "ldo%s4",  &pmic5_nldo,      "vdd-l4-l7-l8"),
9138c2ecf20Sopenharmony_ci	RPMH_VREG("ldo5",   "ldo%s5",  &pmic5_pldo,   "vdd-l5-l16-l17-l18-l19"),
9148c2ecf20Sopenharmony_ci	RPMH_VREG("ldo6",   "ldo%s6",  &pmic5_nldo,      "vdd-l6"),
9158c2ecf20Sopenharmony_ci	RPMH_VREG("ldo7",   "ldo%s7",  &pmic5_nldo,      "vdd-l4-l7-l8"),
9168c2ecf20Sopenharmony_ci	RPMH_VREG("ldo8",   "ldo%s8",  &pmic5_nldo,      "vdd-l4-l7-l8"),
9178c2ecf20Sopenharmony_ci	RPMH_VREG("ldo9",   "ldo%s9",  &pmic5_nldo,      "vdd-l9"),
9188c2ecf20Sopenharmony_ci	RPMH_VREG("ldo10",  "ldo%s10", &pmic5_pldo_lv,   "vdd-l10-l14-l15"),
9198c2ecf20Sopenharmony_ci	RPMH_VREG("ldo11",  "ldo%s11", &pmic5_pldo_lv,   "vdd-l11-l12-l13"),
9208c2ecf20Sopenharmony_ci	RPMH_VREG("ldo12",  "ldo%s12", &pmic5_pldo_lv,   "vdd-l11-l12-l13"),
9218c2ecf20Sopenharmony_ci	RPMH_VREG("ldo13",  "ldo%s13", &pmic5_pldo_lv,   "vdd-l11-l12-l13"),
9228c2ecf20Sopenharmony_ci	RPMH_VREG("ldo14",  "ldo%s14", &pmic5_pldo_lv,   "vdd-l10-l14-l15"),
9238c2ecf20Sopenharmony_ci	RPMH_VREG("ldo15",  "ldo%s15", &pmic5_pldo_lv,   "vdd-l10-l14-l15"),
9248c2ecf20Sopenharmony_ci	RPMH_VREG("ldo16",  "ldo%s16", &pmic5_pldo,   "vdd-l5-l16-l17-l18-l19"),
9258c2ecf20Sopenharmony_ci	RPMH_VREG("ldo17",  "ldo%s17", &pmic5_pldo,   "vdd-l5-l16-l17-l18-l19"),
9268c2ecf20Sopenharmony_ci	RPMH_VREG("ldo18",  "ldo%s18", &pmic5_pldo,   "vdd-l5-l16-l17-l18-l19"),
9278c2ecf20Sopenharmony_ci	RPMH_VREG("ldo19",  "ldo%s19", &pmic5_pldo,   "vdd-l5-l16-l17-l18-l19"),
9288c2ecf20Sopenharmony_ci	{},
9298c2ecf20Sopenharmony_ci};
9308c2ecf20Sopenharmony_ci
9318c2ecf20Sopenharmony_cistatic const struct rpmh_vreg_init_data pm6150l_vreg_data[] = {
9328c2ecf20Sopenharmony_ci	RPMH_VREG("smps1",  "smp%s1",  &pmic5_ftsmps510, "vdd-s1"),
9338c2ecf20Sopenharmony_ci	RPMH_VREG("smps2",  "smp%s2",  &pmic5_ftsmps510, "vdd-s2"),
9348c2ecf20Sopenharmony_ci	RPMH_VREG("smps3",  "smp%s3",  &pmic5_ftsmps510, "vdd-s3"),
9358c2ecf20Sopenharmony_ci	RPMH_VREG("smps4",  "smp%s4",  &pmic5_ftsmps510, "vdd-s4"),
9368c2ecf20Sopenharmony_ci	RPMH_VREG("smps5",  "smp%s5",  &pmic5_ftsmps510, "vdd-s5"),
9378c2ecf20Sopenharmony_ci	RPMH_VREG("smps6",  "smp%s6",  &pmic5_ftsmps510, "vdd-s6"),
9388c2ecf20Sopenharmony_ci	RPMH_VREG("smps7",  "smp%s7",  &pmic5_ftsmps510, "vdd-s7"),
9398c2ecf20Sopenharmony_ci	RPMH_VREG("smps8",  "smp%s8",  &pmic5_hfsmps510, "vdd-s8"),
9408c2ecf20Sopenharmony_ci	RPMH_VREG("ldo1",   "ldo%s1",  &pmic5_pldo_lv,   "vdd-l1-l8"),
9418c2ecf20Sopenharmony_ci	RPMH_VREG("ldo2",   "ldo%s2",  &pmic5_nldo,      "vdd-l2-l3"),
9428c2ecf20Sopenharmony_ci	RPMH_VREG("ldo3",   "ldo%s3",  &pmic5_nldo,      "vdd-l2-l3"),
9438c2ecf20Sopenharmony_ci	RPMH_VREG("ldo4",   "ldo%s4",  &pmic5_pldo,      "vdd-l4-l5-l6"),
9448c2ecf20Sopenharmony_ci	RPMH_VREG("ldo5",   "ldo%s5",  &pmic5_pldo,      "vdd-l4-l5-l6"),
9458c2ecf20Sopenharmony_ci	RPMH_VREG("ldo6",   "ldo%s6",  &pmic5_pldo,      "vdd-l4-l5-l6"),
9468c2ecf20Sopenharmony_ci	RPMH_VREG("ldo7",   "ldo%s7",  &pmic5_pldo,      "vdd-l7-l11"),
9478c2ecf20Sopenharmony_ci	RPMH_VREG("ldo8",   "ldo%s8",  &pmic5_pldo,      "vdd-l1-l8"),
9488c2ecf20Sopenharmony_ci	RPMH_VREG("ldo9",   "ldo%s9",  &pmic5_pldo,      "vdd-l9-l10"),
9498c2ecf20Sopenharmony_ci	RPMH_VREG("ldo10",  "ldo%s10", &pmic5_pldo,      "vdd-l9-l10"),
9508c2ecf20Sopenharmony_ci	RPMH_VREG("ldo11",  "ldo%s11", &pmic5_pldo,      "vdd-l7-l11"),
9518c2ecf20Sopenharmony_ci	RPMH_VREG("bob",    "bob%s1",  &pmic5_bob,       "vdd-bob"),
9528c2ecf20Sopenharmony_ci	{},
9538c2ecf20Sopenharmony_ci};
9548c2ecf20Sopenharmony_ci
9558c2ecf20Sopenharmony_cistatic int rpmh_regulator_probe(struct platform_device *pdev)
9568c2ecf20Sopenharmony_ci{
9578c2ecf20Sopenharmony_ci	struct device *dev = &pdev->dev;
9588c2ecf20Sopenharmony_ci	const struct rpmh_vreg_init_data *vreg_data;
9598c2ecf20Sopenharmony_ci	struct device_node *node;
9608c2ecf20Sopenharmony_ci	struct rpmh_vreg *vreg;
9618c2ecf20Sopenharmony_ci	const char *pmic_id;
9628c2ecf20Sopenharmony_ci	int ret;
9638c2ecf20Sopenharmony_ci
9648c2ecf20Sopenharmony_ci	vreg_data = of_device_get_match_data(dev);
9658c2ecf20Sopenharmony_ci	if (!vreg_data)
9668c2ecf20Sopenharmony_ci		return -ENODEV;
9678c2ecf20Sopenharmony_ci
9688c2ecf20Sopenharmony_ci	ret = of_property_read_string(dev->of_node, "qcom,pmic-id", &pmic_id);
9698c2ecf20Sopenharmony_ci	if (ret < 0) {
9708c2ecf20Sopenharmony_ci		dev_err(dev, "qcom,pmic-id missing in DT node\n");
9718c2ecf20Sopenharmony_ci		return ret;
9728c2ecf20Sopenharmony_ci	}
9738c2ecf20Sopenharmony_ci
9748c2ecf20Sopenharmony_ci	for_each_available_child_of_node(dev->of_node, node) {
9758c2ecf20Sopenharmony_ci		vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL);
9768c2ecf20Sopenharmony_ci		if (!vreg) {
9778c2ecf20Sopenharmony_ci			of_node_put(node);
9788c2ecf20Sopenharmony_ci			return -ENOMEM;
9798c2ecf20Sopenharmony_ci		}
9808c2ecf20Sopenharmony_ci
9818c2ecf20Sopenharmony_ci		ret = rpmh_regulator_init_vreg(vreg, dev, node, pmic_id,
9828c2ecf20Sopenharmony_ci						vreg_data);
9838c2ecf20Sopenharmony_ci		if (ret < 0) {
9848c2ecf20Sopenharmony_ci			of_node_put(node);
9858c2ecf20Sopenharmony_ci			return ret;
9868c2ecf20Sopenharmony_ci		}
9878c2ecf20Sopenharmony_ci	}
9888c2ecf20Sopenharmony_ci
9898c2ecf20Sopenharmony_ci	return 0;
9908c2ecf20Sopenharmony_ci}
9918c2ecf20Sopenharmony_ci
9928c2ecf20Sopenharmony_cistatic const struct of_device_id __maybe_unused rpmh_regulator_match_table[] = {
9938c2ecf20Sopenharmony_ci	{
9948c2ecf20Sopenharmony_ci		.compatible = "qcom,pm8005-rpmh-regulators",
9958c2ecf20Sopenharmony_ci		.data = pm8005_vreg_data,
9968c2ecf20Sopenharmony_ci	},
9978c2ecf20Sopenharmony_ci	{
9988c2ecf20Sopenharmony_ci		.compatible = "qcom,pm8009-rpmh-regulators",
9998c2ecf20Sopenharmony_ci		.data = pm8009_vreg_data,
10008c2ecf20Sopenharmony_ci	},
10018c2ecf20Sopenharmony_ci	{
10028c2ecf20Sopenharmony_ci		.compatible = "qcom,pm8009-1-rpmh-regulators",
10038c2ecf20Sopenharmony_ci		.data = pm8009_1_vreg_data,
10048c2ecf20Sopenharmony_ci	},
10058c2ecf20Sopenharmony_ci	{
10068c2ecf20Sopenharmony_ci		.compatible = "qcom,pm8150-rpmh-regulators",
10078c2ecf20Sopenharmony_ci		.data = pm8150_vreg_data,
10088c2ecf20Sopenharmony_ci	},
10098c2ecf20Sopenharmony_ci	{
10108c2ecf20Sopenharmony_ci		.compatible = "qcom,pm8150l-rpmh-regulators",
10118c2ecf20Sopenharmony_ci		.data = pm8150l_vreg_data,
10128c2ecf20Sopenharmony_ci	},
10138c2ecf20Sopenharmony_ci	{
10148c2ecf20Sopenharmony_ci		.compatible = "qcom,pm8998-rpmh-regulators",
10158c2ecf20Sopenharmony_ci		.data = pm8998_vreg_data,
10168c2ecf20Sopenharmony_ci	},
10178c2ecf20Sopenharmony_ci	{
10188c2ecf20Sopenharmony_ci		.compatible = "qcom,pmi8998-rpmh-regulators",
10198c2ecf20Sopenharmony_ci		.data = pmi8998_vreg_data,
10208c2ecf20Sopenharmony_ci	},
10218c2ecf20Sopenharmony_ci	{
10228c2ecf20Sopenharmony_ci		.compatible = "qcom,pm6150-rpmh-regulators",
10238c2ecf20Sopenharmony_ci		.data = pm6150_vreg_data,
10248c2ecf20Sopenharmony_ci	},
10258c2ecf20Sopenharmony_ci	{
10268c2ecf20Sopenharmony_ci		.compatible = "qcom,pm6150l-rpmh-regulators",
10278c2ecf20Sopenharmony_ci		.data = pm6150l_vreg_data,
10288c2ecf20Sopenharmony_ci	},
10298c2ecf20Sopenharmony_ci	{}
10308c2ecf20Sopenharmony_ci};
10318c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, rpmh_regulator_match_table);
10328c2ecf20Sopenharmony_ci
10338c2ecf20Sopenharmony_cistatic struct platform_driver rpmh_regulator_driver = {
10348c2ecf20Sopenharmony_ci	.driver = {
10358c2ecf20Sopenharmony_ci		.name = "qcom-rpmh-regulator",
10368c2ecf20Sopenharmony_ci		.of_match_table	= of_match_ptr(rpmh_regulator_match_table),
10378c2ecf20Sopenharmony_ci	},
10388c2ecf20Sopenharmony_ci	.probe = rpmh_regulator_probe,
10398c2ecf20Sopenharmony_ci};
10408c2ecf20Sopenharmony_cimodule_platform_driver(rpmh_regulator_driver);
10418c2ecf20Sopenharmony_ci
10428c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Qualcomm RPMh regulator driver");
10438c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2");
1044