162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci//
362306a36Sopenharmony_ci// Copyright (c) 2019 MediaTek Inc.
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/mfd/mt6358/registers.h>
662306a36Sopenharmony_ci#include <linux/mfd/mt6397/core.h>
762306a36Sopenharmony_ci#include <linux/module.h>
862306a36Sopenharmony_ci#include <linux/of.h>
962306a36Sopenharmony_ci#include <linux/platform_device.h>
1062306a36Sopenharmony_ci#include <linux/regmap.h>
1162306a36Sopenharmony_ci#include <linux/regulator/driver.h>
1262306a36Sopenharmony_ci#include <linux/regulator/machine.h>
1362306a36Sopenharmony_ci#include <linux/regulator/mt6358-regulator.h>
1462306a36Sopenharmony_ci#include <linux/regulator/of_regulator.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#define MT6358_BUCK_MODE_AUTO	0
1762306a36Sopenharmony_ci#define MT6358_BUCK_MODE_FORCE_PWM	1
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci/*
2062306a36Sopenharmony_ci * MT6358 regulators' information
2162306a36Sopenharmony_ci *
2262306a36Sopenharmony_ci * @desc: standard fields of regulator description.
2362306a36Sopenharmony_ci * @qi: Mask for query enable signal status of regulators
2462306a36Sopenharmony_ci */
2562306a36Sopenharmony_cistruct mt6358_regulator_info {
2662306a36Sopenharmony_ci	struct regulator_desc desc;
2762306a36Sopenharmony_ci	u32 status_reg;
2862306a36Sopenharmony_ci	u32 qi;
2962306a36Sopenharmony_ci	const u32 *index_table;
3062306a36Sopenharmony_ci	unsigned int n_table;
3162306a36Sopenharmony_ci	u32 da_vsel_reg;
3262306a36Sopenharmony_ci	u32 da_vsel_mask;
3362306a36Sopenharmony_ci	u32 modeset_reg;
3462306a36Sopenharmony_ci	u32 modeset_mask;
3562306a36Sopenharmony_ci};
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#define to_regulator_info(x) container_of((x), struct mt6358_regulator_info, desc)
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci#define MT6358_BUCK(match, vreg, min, max, step,		\
4062306a36Sopenharmony_ci	vosel_mask, _da_vsel_reg, _da_vsel_mask,	\
4162306a36Sopenharmony_ci	_modeset_reg, _modeset_shift)		\
4262306a36Sopenharmony_ci[MT6358_ID_##vreg] = {	\
4362306a36Sopenharmony_ci	.desc = {	\
4462306a36Sopenharmony_ci		.name = #vreg,	\
4562306a36Sopenharmony_ci		.of_match = of_match_ptr(match),	\
4662306a36Sopenharmony_ci		.ops = &mt6358_buck_ops,	\
4762306a36Sopenharmony_ci		.type = REGULATOR_VOLTAGE,	\
4862306a36Sopenharmony_ci		.id = MT6358_ID_##vreg,		\
4962306a36Sopenharmony_ci		.owner = THIS_MODULE,		\
5062306a36Sopenharmony_ci		.n_voltages = ((max) - (min)) / (step) + 1,	\
5162306a36Sopenharmony_ci		.min_uV = (min),		\
5262306a36Sopenharmony_ci		.uV_step = (step),		\
5362306a36Sopenharmony_ci		.vsel_reg = MT6358_BUCK_##vreg##_ELR0,	\
5462306a36Sopenharmony_ci		.vsel_mask = vosel_mask,	\
5562306a36Sopenharmony_ci		.enable_reg = MT6358_BUCK_##vreg##_CON0,	\
5662306a36Sopenharmony_ci		.enable_mask = BIT(0),	\
5762306a36Sopenharmony_ci		.of_map_mode = mt6358_map_mode,	\
5862306a36Sopenharmony_ci	},	\
5962306a36Sopenharmony_ci	.status_reg = MT6358_BUCK_##vreg##_DBG1,	\
6062306a36Sopenharmony_ci	.qi = BIT(0),	\
6162306a36Sopenharmony_ci	.da_vsel_reg = _da_vsel_reg,	\
6262306a36Sopenharmony_ci	.da_vsel_mask = _da_vsel_mask,	\
6362306a36Sopenharmony_ci	.modeset_reg = _modeset_reg,	\
6462306a36Sopenharmony_ci	.modeset_mask = BIT(_modeset_shift),	\
6562306a36Sopenharmony_ci}
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci#define MT6358_LDO(match, vreg, ldo_volt_table,	\
6862306a36Sopenharmony_ci	ldo_index_table, enreg, enbit, vosel,	\
6962306a36Sopenharmony_ci	vosel_mask)	\
7062306a36Sopenharmony_ci[MT6358_ID_##vreg] = {	\
7162306a36Sopenharmony_ci	.desc = {	\
7262306a36Sopenharmony_ci		.name = #vreg,	\
7362306a36Sopenharmony_ci		.of_match = of_match_ptr(match),	\
7462306a36Sopenharmony_ci		.ops = &mt6358_volt_table_ops,	\
7562306a36Sopenharmony_ci		.type = REGULATOR_VOLTAGE,	\
7662306a36Sopenharmony_ci		.id = MT6358_ID_##vreg,	\
7762306a36Sopenharmony_ci		.owner = THIS_MODULE,	\
7862306a36Sopenharmony_ci		.n_voltages = ARRAY_SIZE(ldo_volt_table),	\
7962306a36Sopenharmony_ci		.volt_table = ldo_volt_table,	\
8062306a36Sopenharmony_ci		.vsel_reg = vosel,	\
8162306a36Sopenharmony_ci		.vsel_mask = vosel_mask,	\
8262306a36Sopenharmony_ci		.enable_reg = enreg,	\
8362306a36Sopenharmony_ci		.enable_mask = BIT(enbit),	\
8462306a36Sopenharmony_ci	},	\
8562306a36Sopenharmony_ci	.status_reg = MT6358_LDO_##vreg##_CON1,	\
8662306a36Sopenharmony_ci	.qi = BIT(15),	\
8762306a36Sopenharmony_ci	.index_table = ldo_index_table,	\
8862306a36Sopenharmony_ci	.n_table = ARRAY_SIZE(ldo_index_table),	\
8962306a36Sopenharmony_ci}
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci#define MT6358_LDO1(match, vreg, min, max, step,	\
9262306a36Sopenharmony_ci	_da_vsel_reg, _da_vsel_mask,	\
9362306a36Sopenharmony_ci	vosel, vosel_mask)	\
9462306a36Sopenharmony_ci[MT6358_ID_##vreg] = {	\
9562306a36Sopenharmony_ci	.desc = {	\
9662306a36Sopenharmony_ci		.name = #vreg,	\
9762306a36Sopenharmony_ci		.of_match = of_match_ptr(match),	\
9862306a36Sopenharmony_ci		.ops = &mt6358_volt_range_ops,	\
9962306a36Sopenharmony_ci		.type = REGULATOR_VOLTAGE,	\
10062306a36Sopenharmony_ci		.id = MT6358_ID_##vreg,	\
10162306a36Sopenharmony_ci		.owner = THIS_MODULE,	\
10262306a36Sopenharmony_ci		.n_voltages = ((max) - (min)) / (step) + 1,	\
10362306a36Sopenharmony_ci		.min_uV = (min),		\
10462306a36Sopenharmony_ci		.uV_step = (step),		\
10562306a36Sopenharmony_ci		.vsel_reg = vosel,	\
10662306a36Sopenharmony_ci		.vsel_mask = vosel_mask,	\
10762306a36Sopenharmony_ci		.enable_reg = MT6358_LDO_##vreg##_CON0,	\
10862306a36Sopenharmony_ci		.enable_mask = BIT(0),	\
10962306a36Sopenharmony_ci	},	\
11062306a36Sopenharmony_ci	.da_vsel_reg = _da_vsel_reg,	\
11162306a36Sopenharmony_ci	.da_vsel_mask = _da_vsel_mask,	\
11262306a36Sopenharmony_ci	.status_reg = MT6358_LDO_##vreg##_DBG1,	\
11362306a36Sopenharmony_ci	.qi = BIT(0),	\
11462306a36Sopenharmony_ci}
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci#define MT6358_REG_FIXED(match, vreg,	\
11762306a36Sopenharmony_ci	enreg, enbit, volt)	\
11862306a36Sopenharmony_ci[MT6358_ID_##vreg] = {	\
11962306a36Sopenharmony_ci	.desc = {	\
12062306a36Sopenharmony_ci		.name = #vreg,	\
12162306a36Sopenharmony_ci		.of_match = of_match_ptr(match),	\
12262306a36Sopenharmony_ci		.ops = &mt6358_volt_fixed_ops,	\
12362306a36Sopenharmony_ci		.type = REGULATOR_VOLTAGE,	\
12462306a36Sopenharmony_ci		.id = MT6358_ID_##vreg,	\
12562306a36Sopenharmony_ci		.owner = THIS_MODULE,	\
12662306a36Sopenharmony_ci		.n_voltages = 1,	\
12762306a36Sopenharmony_ci		.enable_reg = enreg,	\
12862306a36Sopenharmony_ci		.enable_mask = BIT(enbit),	\
12962306a36Sopenharmony_ci		.min_uV = volt,	\
13062306a36Sopenharmony_ci	},	\
13162306a36Sopenharmony_ci	.status_reg = MT6358_LDO_##vreg##_CON1,	\
13262306a36Sopenharmony_ci	.qi = BIT(15),							\
13362306a36Sopenharmony_ci}
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci#define MT6366_BUCK(match, vreg, min, max, step,		\
13662306a36Sopenharmony_ci	vosel_mask, _da_vsel_reg, _da_vsel_mask,	\
13762306a36Sopenharmony_ci	_modeset_reg, _modeset_shift)		\
13862306a36Sopenharmony_ci[MT6366_ID_##vreg] = {	\
13962306a36Sopenharmony_ci	.desc = {	\
14062306a36Sopenharmony_ci		.name = #vreg,	\
14162306a36Sopenharmony_ci		.of_match = of_match_ptr(match),	\
14262306a36Sopenharmony_ci		.ops = &mt6358_buck_ops,	\
14362306a36Sopenharmony_ci		.type = REGULATOR_VOLTAGE,	\
14462306a36Sopenharmony_ci		.id = MT6366_ID_##vreg,		\
14562306a36Sopenharmony_ci		.owner = THIS_MODULE,		\
14662306a36Sopenharmony_ci		.n_voltages = ((max) - (min)) / (step) + 1,	\
14762306a36Sopenharmony_ci		.min_uV = (min),		\
14862306a36Sopenharmony_ci		.uV_step = (step),		\
14962306a36Sopenharmony_ci		.vsel_reg = MT6358_BUCK_##vreg##_ELR0,	\
15062306a36Sopenharmony_ci		.vsel_mask = vosel_mask,	\
15162306a36Sopenharmony_ci		.enable_reg = MT6358_BUCK_##vreg##_CON0,	\
15262306a36Sopenharmony_ci		.enable_mask = BIT(0),	\
15362306a36Sopenharmony_ci		.of_map_mode = mt6358_map_mode,	\
15462306a36Sopenharmony_ci	},	\
15562306a36Sopenharmony_ci	.status_reg = MT6358_BUCK_##vreg##_DBG1,	\
15662306a36Sopenharmony_ci	.qi = BIT(0),	\
15762306a36Sopenharmony_ci	.da_vsel_reg = _da_vsel_reg,	\
15862306a36Sopenharmony_ci	.da_vsel_mask = _da_vsel_mask,	\
15962306a36Sopenharmony_ci	.modeset_reg = _modeset_reg,	\
16062306a36Sopenharmony_ci	.modeset_mask = BIT(_modeset_shift),	\
16162306a36Sopenharmony_ci}
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci#define MT6366_LDO(match, vreg, ldo_volt_table,	\
16462306a36Sopenharmony_ci	ldo_index_table, enreg, enbit, vosel,	\
16562306a36Sopenharmony_ci	vosel_mask)	\
16662306a36Sopenharmony_ci[MT6366_ID_##vreg] = {	\
16762306a36Sopenharmony_ci	.desc = {	\
16862306a36Sopenharmony_ci		.name = #vreg,	\
16962306a36Sopenharmony_ci		.of_match = of_match_ptr(match),	\
17062306a36Sopenharmony_ci		.ops = &mt6358_volt_table_ops,	\
17162306a36Sopenharmony_ci		.type = REGULATOR_VOLTAGE,	\
17262306a36Sopenharmony_ci		.id = MT6366_ID_##vreg,	\
17362306a36Sopenharmony_ci		.owner = THIS_MODULE,	\
17462306a36Sopenharmony_ci		.n_voltages = ARRAY_SIZE(ldo_volt_table),	\
17562306a36Sopenharmony_ci		.volt_table = ldo_volt_table,	\
17662306a36Sopenharmony_ci		.vsel_reg = vosel,	\
17762306a36Sopenharmony_ci		.vsel_mask = vosel_mask,	\
17862306a36Sopenharmony_ci		.enable_reg = enreg,	\
17962306a36Sopenharmony_ci		.enable_mask = BIT(enbit),	\
18062306a36Sopenharmony_ci	},	\
18162306a36Sopenharmony_ci	.status_reg = MT6358_LDO_##vreg##_CON1,	\
18262306a36Sopenharmony_ci	.qi = BIT(15),	\
18362306a36Sopenharmony_ci	.index_table = ldo_index_table,	\
18462306a36Sopenharmony_ci	.n_table = ARRAY_SIZE(ldo_index_table),	\
18562306a36Sopenharmony_ci}
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_ci#define MT6366_LDO1(match, vreg, min, max, step,	\
18862306a36Sopenharmony_ci	_da_vsel_reg, _da_vsel_mask,	\
18962306a36Sopenharmony_ci	vosel, vosel_mask)	\
19062306a36Sopenharmony_ci[MT6366_ID_##vreg] = {	\
19162306a36Sopenharmony_ci	.desc = {	\
19262306a36Sopenharmony_ci		.name = #vreg,	\
19362306a36Sopenharmony_ci		.of_match = of_match_ptr(match),	\
19462306a36Sopenharmony_ci		.ops = &mt6358_volt_range_ops,	\
19562306a36Sopenharmony_ci		.type = REGULATOR_VOLTAGE,	\
19662306a36Sopenharmony_ci		.id = MT6366_ID_##vreg,	\
19762306a36Sopenharmony_ci		.owner = THIS_MODULE,	\
19862306a36Sopenharmony_ci		.n_voltages = ((max) - (min)) / (step) + 1,	\
19962306a36Sopenharmony_ci		.min_uV = (min),		\
20062306a36Sopenharmony_ci		.uV_step = (step),		\
20162306a36Sopenharmony_ci		.vsel_reg = vosel,	\
20262306a36Sopenharmony_ci		.vsel_mask = vosel_mask,	\
20362306a36Sopenharmony_ci		.enable_reg = MT6358_LDO_##vreg##_CON0,	\
20462306a36Sopenharmony_ci		.enable_mask = BIT(0),	\
20562306a36Sopenharmony_ci	},	\
20662306a36Sopenharmony_ci	.da_vsel_reg = _da_vsel_reg,	\
20762306a36Sopenharmony_ci	.da_vsel_mask = _da_vsel_mask,	\
20862306a36Sopenharmony_ci	.status_reg = MT6358_LDO_##vreg##_DBG1,	\
20962306a36Sopenharmony_ci	.qi = BIT(0),	\
21062306a36Sopenharmony_ci}
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci#define MT6366_REG_FIXED(match, vreg,	\
21362306a36Sopenharmony_ci	enreg, enbit, volt)	\
21462306a36Sopenharmony_ci[MT6366_ID_##vreg] = {	\
21562306a36Sopenharmony_ci	.desc = {	\
21662306a36Sopenharmony_ci		.name = #vreg,	\
21762306a36Sopenharmony_ci		.of_match = of_match_ptr(match),	\
21862306a36Sopenharmony_ci		.ops = &mt6358_volt_fixed_ops,	\
21962306a36Sopenharmony_ci		.type = REGULATOR_VOLTAGE,	\
22062306a36Sopenharmony_ci		.id = MT6366_ID_##vreg,	\
22162306a36Sopenharmony_ci		.owner = THIS_MODULE,	\
22262306a36Sopenharmony_ci		.n_voltages = 1,	\
22362306a36Sopenharmony_ci		.enable_reg = enreg,	\
22462306a36Sopenharmony_ci		.enable_mask = BIT(enbit),	\
22562306a36Sopenharmony_ci		.min_uV = volt,	\
22662306a36Sopenharmony_ci	},	\
22762306a36Sopenharmony_ci	.status_reg = MT6358_LDO_##vreg##_CON1,	\
22862306a36Sopenharmony_ci	.qi = BIT(15),							\
22962306a36Sopenharmony_ci}
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_cistatic const unsigned int vdram2_voltages[] = {
23362306a36Sopenharmony_ci	600000, 1800000,
23462306a36Sopenharmony_ci};
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_cistatic const unsigned int vsim_voltages[] = {
23762306a36Sopenharmony_ci	1700000, 1800000, 2700000, 3000000, 3100000,
23862306a36Sopenharmony_ci};
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_cistatic const unsigned int vibr_voltages[] = {
24162306a36Sopenharmony_ci	1200000, 1300000, 1500000, 1800000,
24262306a36Sopenharmony_ci	2000000, 2800000, 3000000, 3300000,
24362306a36Sopenharmony_ci};
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_cistatic const unsigned int vusb_voltages[] = {
24662306a36Sopenharmony_ci	3000000, 3100000,
24762306a36Sopenharmony_ci};
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_cistatic const unsigned int vcamd_voltages[] = {
25062306a36Sopenharmony_ci	900000, 1000000, 1100000, 1200000,
25162306a36Sopenharmony_ci	1300000, 1500000, 1800000,
25262306a36Sopenharmony_ci};
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_cistatic const unsigned int vefuse_voltages[] = {
25562306a36Sopenharmony_ci	1700000, 1800000, 1900000,
25662306a36Sopenharmony_ci};
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_cistatic const unsigned int vmch_vemc_voltages[] = {
25962306a36Sopenharmony_ci	2900000, 3000000, 3300000,
26062306a36Sopenharmony_ci};
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_cistatic const unsigned int vcama_voltages[] = {
26362306a36Sopenharmony_ci	1800000, 2500000, 2700000,
26462306a36Sopenharmony_ci	2800000, 2900000, 3000000,
26562306a36Sopenharmony_ci};
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_cistatic const unsigned int vcn33_voltages[] = {
26862306a36Sopenharmony_ci	3300000, 3400000, 3500000,
26962306a36Sopenharmony_ci};
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_cistatic const unsigned int vmc_voltages[] = {
27262306a36Sopenharmony_ci	1800000, 2900000, 3000000, 3300000,
27362306a36Sopenharmony_ci};
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_cistatic const unsigned int vldo28_voltages[] = {
27662306a36Sopenharmony_ci	2800000, 3000000,
27762306a36Sopenharmony_ci};
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_cistatic const u32 vdram2_idx[] = {
28062306a36Sopenharmony_ci	0, 12,
28162306a36Sopenharmony_ci};
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_cistatic const u32 vsim_idx[] = {
28462306a36Sopenharmony_ci	3, 4, 8, 11, 12,
28562306a36Sopenharmony_ci};
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_cistatic const u32 vibr_idx[] = {
28862306a36Sopenharmony_ci	0, 1, 2, 4, 5, 9, 11, 13,
28962306a36Sopenharmony_ci};
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_cistatic const u32 vusb_idx[] = {
29262306a36Sopenharmony_ci	3, 4,
29362306a36Sopenharmony_ci};
29462306a36Sopenharmony_ci
29562306a36Sopenharmony_cistatic const u32 vcamd_idx[] = {
29662306a36Sopenharmony_ci	3, 4, 5, 6, 7, 9, 12,
29762306a36Sopenharmony_ci};
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_cistatic const u32 vefuse_idx[] = {
30062306a36Sopenharmony_ci	11, 12, 13,
30162306a36Sopenharmony_ci};
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_cistatic const u32 vmch_vemc_idx[] = {
30462306a36Sopenharmony_ci	2, 3, 5,
30562306a36Sopenharmony_ci};
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_cistatic const u32 vcama_idx[] = {
30862306a36Sopenharmony_ci	0, 7, 9, 10, 11, 12,
30962306a36Sopenharmony_ci};
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_cistatic const u32 vcn33_idx[] = {
31262306a36Sopenharmony_ci	1, 2, 3,
31362306a36Sopenharmony_ci};
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_cistatic const u32 vmc_idx[] = {
31662306a36Sopenharmony_ci	4, 10, 11, 13,
31762306a36Sopenharmony_ci};
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_cistatic const u32 vldo28_idx[] = {
32062306a36Sopenharmony_ci	1, 3,
32162306a36Sopenharmony_ci};
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_cistatic unsigned int mt6358_map_mode(unsigned int mode)
32462306a36Sopenharmony_ci{
32562306a36Sopenharmony_ci	return mode == MT6358_BUCK_MODE_AUTO ?
32662306a36Sopenharmony_ci		REGULATOR_MODE_NORMAL : REGULATOR_MODE_FAST;
32762306a36Sopenharmony_ci}
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_cistatic int mt6358_set_voltage_sel(struct regulator_dev *rdev,
33062306a36Sopenharmony_ci				  unsigned int selector)
33162306a36Sopenharmony_ci{
33262306a36Sopenharmony_ci	const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
33362306a36Sopenharmony_ci	int idx, ret;
33462306a36Sopenharmony_ci	const u32 *pvol;
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci	pvol = info->index_table;
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci	idx = pvol[selector];
33962306a36Sopenharmony_ci	idx <<= ffs(info->desc.vsel_mask) - 1;
34062306a36Sopenharmony_ci	ret = regmap_update_bits(rdev->regmap, info->desc.vsel_reg,
34162306a36Sopenharmony_ci				 info->desc.vsel_mask, idx);
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci	return ret;
34462306a36Sopenharmony_ci}
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_cistatic int mt6358_get_voltage_sel(struct regulator_dev *rdev)
34762306a36Sopenharmony_ci{
34862306a36Sopenharmony_ci	const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
34962306a36Sopenharmony_ci	int idx, ret;
35062306a36Sopenharmony_ci	u32 selector;
35162306a36Sopenharmony_ci	const u32 *pvol;
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ci	ret = regmap_read(rdev->regmap, info->desc.vsel_reg, &selector);
35462306a36Sopenharmony_ci	if (ret != 0) {
35562306a36Sopenharmony_ci		dev_info(&rdev->dev,
35662306a36Sopenharmony_ci			 "Failed to get mt6358 %s vsel reg: %d\n",
35762306a36Sopenharmony_ci			 info->desc.name, ret);
35862306a36Sopenharmony_ci		return ret;
35962306a36Sopenharmony_ci	}
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci	selector = (selector & info->desc.vsel_mask) >>
36262306a36Sopenharmony_ci			(ffs(info->desc.vsel_mask) - 1);
36362306a36Sopenharmony_ci	pvol = info->index_table;
36462306a36Sopenharmony_ci	for (idx = 0; idx < info->desc.n_voltages; idx++) {
36562306a36Sopenharmony_ci		if (pvol[idx] == selector)
36662306a36Sopenharmony_ci			return idx;
36762306a36Sopenharmony_ci	}
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci	return -EINVAL;
37062306a36Sopenharmony_ci}
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_cistatic int mt6358_get_buck_voltage_sel(struct regulator_dev *rdev)
37362306a36Sopenharmony_ci{
37462306a36Sopenharmony_ci	const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
37562306a36Sopenharmony_ci	int ret, regval;
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_ci	ret = regmap_read(rdev->regmap, info->da_vsel_reg, &regval);
37862306a36Sopenharmony_ci	if (ret != 0) {
37962306a36Sopenharmony_ci		dev_err(&rdev->dev,
38062306a36Sopenharmony_ci			"Failed to get mt6358 Buck %s vsel reg: %d\n",
38162306a36Sopenharmony_ci			info->desc.name, ret);
38262306a36Sopenharmony_ci		return ret;
38362306a36Sopenharmony_ci	}
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci	ret = (regval & info->da_vsel_mask) >> (ffs(info->da_vsel_mask) - 1);
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci	return ret;
38862306a36Sopenharmony_ci}
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_cistatic int mt6358_get_status(struct regulator_dev *rdev)
39162306a36Sopenharmony_ci{
39262306a36Sopenharmony_ci	const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
39362306a36Sopenharmony_ci	int ret;
39462306a36Sopenharmony_ci	u32 regval;
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ci	ret = regmap_read(rdev->regmap, info->status_reg, &regval);
39762306a36Sopenharmony_ci	if (ret != 0) {
39862306a36Sopenharmony_ci		dev_info(&rdev->dev, "Failed to get enable reg: %d\n", ret);
39962306a36Sopenharmony_ci		return ret;
40062306a36Sopenharmony_ci	}
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_ci	return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF;
40362306a36Sopenharmony_ci}
40462306a36Sopenharmony_ci
40562306a36Sopenharmony_cistatic int mt6358_regulator_set_mode(struct regulator_dev *rdev,
40662306a36Sopenharmony_ci				     unsigned int mode)
40762306a36Sopenharmony_ci{
40862306a36Sopenharmony_ci	const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
40962306a36Sopenharmony_ci	int val;
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_ci	switch (mode) {
41262306a36Sopenharmony_ci	case REGULATOR_MODE_FAST:
41362306a36Sopenharmony_ci		val = MT6358_BUCK_MODE_FORCE_PWM;
41462306a36Sopenharmony_ci		break;
41562306a36Sopenharmony_ci	case REGULATOR_MODE_NORMAL:
41662306a36Sopenharmony_ci		val = MT6358_BUCK_MODE_AUTO;
41762306a36Sopenharmony_ci		break;
41862306a36Sopenharmony_ci	default:
41962306a36Sopenharmony_ci		return -EINVAL;
42062306a36Sopenharmony_ci	}
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci	dev_dbg(&rdev->dev, "mt6358 buck set_mode %#x, %#x, %#x\n",
42362306a36Sopenharmony_ci		info->modeset_reg, info->modeset_mask, val);
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_ci	val <<= ffs(info->modeset_mask) - 1;
42662306a36Sopenharmony_ci
42762306a36Sopenharmony_ci	return regmap_update_bits(rdev->regmap, info->modeset_reg,
42862306a36Sopenharmony_ci				  info->modeset_mask, val);
42962306a36Sopenharmony_ci}
43062306a36Sopenharmony_ci
43162306a36Sopenharmony_cistatic unsigned int mt6358_regulator_get_mode(struct regulator_dev *rdev)
43262306a36Sopenharmony_ci{
43362306a36Sopenharmony_ci	const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
43462306a36Sopenharmony_ci	int ret, regval;
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_ci	ret = regmap_read(rdev->regmap, info->modeset_reg, &regval);
43762306a36Sopenharmony_ci	if (ret != 0) {
43862306a36Sopenharmony_ci		dev_err(&rdev->dev,
43962306a36Sopenharmony_ci			"Failed to get mt6358 buck mode: %d\n", ret);
44062306a36Sopenharmony_ci		return ret;
44162306a36Sopenharmony_ci	}
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci	switch ((regval & info->modeset_mask) >> (ffs(info->modeset_mask) - 1)) {
44462306a36Sopenharmony_ci	case MT6358_BUCK_MODE_AUTO:
44562306a36Sopenharmony_ci		return REGULATOR_MODE_NORMAL;
44662306a36Sopenharmony_ci	case MT6358_BUCK_MODE_FORCE_PWM:
44762306a36Sopenharmony_ci		return REGULATOR_MODE_FAST;
44862306a36Sopenharmony_ci	default:
44962306a36Sopenharmony_ci		return -EINVAL;
45062306a36Sopenharmony_ci	}
45162306a36Sopenharmony_ci}
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_cistatic const struct regulator_ops mt6358_buck_ops = {
45462306a36Sopenharmony_ci	.list_voltage = regulator_list_voltage_linear,
45562306a36Sopenharmony_ci	.map_voltage = regulator_map_voltage_linear,
45662306a36Sopenharmony_ci	.set_voltage_sel = regulator_set_voltage_sel_regmap,
45762306a36Sopenharmony_ci	.get_voltage_sel = mt6358_get_buck_voltage_sel,
45862306a36Sopenharmony_ci	.set_voltage_time_sel = regulator_set_voltage_time_sel,
45962306a36Sopenharmony_ci	.enable = regulator_enable_regmap,
46062306a36Sopenharmony_ci	.disable = regulator_disable_regmap,
46162306a36Sopenharmony_ci	.is_enabled = regulator_is_enabled_regmap,
46262306a36Sopenharmony_ci	.get_status = mt6358_get_status,
46362306a36Sopenharmony_ci	.set_mode = mt6358_regulator_set_mode,
46462306a36Sopenharmony_ci	.get_mode = mt6358_regulator_get_mode,
46562306a36Sopenharmony_ci};
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_cistatic const struct regulator_ops mt6358_volt_range_ops = {
46862306a36Sopenharmony_ci	.list_voltage = regulator_list_voltage_linear,
46962306a36Sopenharmony_ci	.map_voltage = regulator_map_voltage_linear,
47062306a36Sopenharmony_ci	.set_voltage_sel = regulator_set_voltage_sel_regmap,
47162306a36Sopenharmony_ci	.get_voltage_sel = mt6358_get_buck_voltage_sel,
47262306a36Sopenharmony_ci	.set_voltage_time_sel = regulator_set_voltage_time_sel,
47362306a36Sopenharmony_ci	.enable = regulator_enable_regmap,
47462306a36Sopenharmony_ci	.disable = regulator_disable_regmap,
47562306a36Sopenharmony_ci	.is_enabled = regulator_is_enabled_regmap,
47662306a36Sopenharmony_ci	.get_status = mt6358_get_status,
47762306a36Sopenharmony_ci};
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_cistatic const struct regulator_ops mt6358_volt_table_ops = {
48062306a36Sopenharmony_ci	.list_voltage = regulator_list_voltage_table,
48162306a36Sopenharmony_ci	.map_voltage = regulator_map_voltage_iterate,
48262306a36Sopenharmony_ci	.set_voltage_sel = mt6358_set_voltage_sel,
48362306a36Sopenharmony_ci	.get_voltage_sel = mt6358_get_voltage_sel,
48462306a36Sopenharmony_ci	.set_voltage_time_sel = regulator_set_voltage_time_sel,
48562306a36Sopenharmony_ci	.enable = regulator_enable_regmap,
48662306a36Sopenharmony_ci	.disable = regulator_disable_regmap,
48762306a36Sopenharmony_ci	.is_enabled = regulator_is_enabled_regmap,
48862306a36Sopenharmony_ci	.get_status = mt6358_get_status,
48962306a36Sopenharmony_ci};
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_cistatic const struct regulator_ops mt6358_volt_fixed_ops = {
49262306a36Sopenharmony_ci	.list_voltage = regulator_list_voltage_linear,
49362306a36Sopenharmony_ci	.enable = regulator_enable_regmap,
49462306a36Sopenharmony_ci	.disable = regulator_disable_regmap,
49562306a36Sopenharmony_ci	.is_enabled = regulator_is_enabled_regmap,
49662306a36Sopenharmony_ci	.get_status = mt6358_get_status,
49762306a36Sopenharmony_ci};
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci/* The array is indexed by id(MT6358_ID_XXX) */
50062306a36Sopenharmony_cistatic const struct mt6358_regulator_info mt6358_regulators[] = {
50162306a36Sopenharmony_ci	MT6358_BUCK("buck_vdram1", VDRAM1, 500000, 2087500, 12500,
50262306a36Sopenharmony_ci		    0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, MT6358_VDRAM1_ANA_CON0, 8),
50362306a36Sopenharmony_ci	MT6358_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250,
50462306a36Sopenharmony_ci		    0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 1),
50562306a36Sopenharmony_ci	MT6358_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
50662306a36Sopenharmony_ci		    0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, MT6358_VPA_ANA_CON0, 3),
50762306a36Sopenharmony_ci	MT6358_BUCK("buck_vproc11", VPROC11, 500000, 1293750, 6250,
50862306a36Sopenharmony_ci		    0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 1),
50962306a36Sopenharmony_ci	MT6358_BUCK("buck_vproc12", VPROC12, 500000, 1293750, 6250,
51062306a36Sopenharmony_ci		    0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 2),
51162306a36Sopenharmony_ci	MT6358_BUCK("buck_vgpu", VGPU, 500000, 1293750, 6250,
51262306a36Sopenharmony_ci		    0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 2),
51362306a36Sopenharmony_ci	MT6358_BUCK("buck_vs2", VS2, 500000, 2087500, 12500,
51462306a36Sopenharmony_ci		    0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, MT6358_VS2_ANA_CON0, 8),
51562306a36Sopenharmony_ci	MT6358_BUCK("buck_vmodem", VMODEM, 500000, 1293750, 6250,
51662306a36Sopenharmony_ci		    0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, MT6358_VMODEM_ANA_CON0, 8),
51762306a36Sopenharmony_ci	MT6358_BUCK("buck_vs1", VS1, 1000000, 2587500, 12500,
51862306a36Sopenharmony_ci		    0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, MT6358_VS1_ANA_CON0, 8),
51962306a36Sopenharmony_ci	MT6358_REG_FIXED("ldo_vrf12", VRF12,
52062306a36Sopenharmony_ci			 MT6358_LDO_VRF12_CON0, 0, 1200000),
52162306a36Sopenharmony_ci	MT6358_REG_FIXED("ldo_vio18", VIO18,
52262306a36Sopenharmony_ci			 MT6358_LDO_VIO18_CON0, 0, 1800000),
52362306a36Sopenharmony_ci	MT6358_REG_FIXED("ldo_vcamio", VCAMIO,
52462306a36Sopenharmony_ci			 MT6358_LDO_VCAMIO_CON0, 0, 1800000),
52562306a36Sopenharmony_ci	MT6358_REG_FIXED("ldo_vcn18", VCN18, MT6358_LDO_VCN18_CON0, 0, 1800000),
52662306a36Sopenharmony_ci	MT6358_REG_FIXED("ldo_vfe28", VFE28, MT6358_LDO_VFE28_CON0, 0, 2800000),
52762306a36Sopenharmony_ci	MT6358_REG_FIXED("ldo_vcn28", VCN28, MT6358_LDO_VCN28_CON0, 0, 2800000),
52862306a36Sopenharmony_ci	MT6358_REG_FIXED("ldo_vxo22", VXO22, MT6358_LDO_VXO22_CON0, 0, 2200000),
52962306a36Sopenharmony_ci	MT6358_REG_FIXED("ldo_vaux18", VAUX18,
53062306a36Sopenharmony_ci			 MT6358_LDO_VAUX18_CON0, 0, 1800000),
53162306a36Sopenharmony_ci	MT6358_REG_FIXED("ldo_vbif28", VBIF28,
53262306a36Sopenharmony_ci			 MT6358_LDO_VBIF28_CON0, 0, 2800000),
53362306a36Sopenharmony_ci	MT6358_REG_FIXED("ldo_vio28", VIO28, MT6358_LDO_VIO28_CON0, 0, 2800000),
53462306a36Sopenharmony_ci	MT6358_REG_FIXED("ldo_va12", VA12, MT6358_LDO_VA12_CON0, 0, 1200000),
53562306a36Sopenharmony_ci	MT6358_REG_FIXED("ldo_vrf18", VRF18, MT6358_LDO_VRF18_CON0, 0, 1800000),
53662306a36Sopenharmony_ci	MT6358_REG_FIXED("ldo_vaud28", VAUD28,
53762306a36Sopenharmony_ci			 MT6358_LDO_VAUD28_CON0, 0, 2800000),
53862306a36Sopenharmony_ci	MT6358_LDO("ldo_vdram2", VDRAM2, vdram2_voltages, vdram2_idx,
53962306a36Sopenharmony_ci		   MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0xf),
54062306a36Sopenharmony_ci	MT6358_LDO("ldo_vsim1", VSIM1, vsim_voltages, vsim_idx,
54162306a36Sopenharmony_ci		   MT6358_LDO_VSIM1_CON0, 0, MT6358_VSIM1_ANA_CON0, 0xf00),
54262306a36Sopenharmony_ci	MT6358_LDO("ldo_vibr", VIBR, vibr_voltages, vibr_idx,
54362306a36Sopenharmony_ci		   MT6358_LDO_VIBR_CON0, 0, MT6358_VIBR_ANA_CON0, 0xf00),
54462306a36Sopenharmony_ci	MT6358_LDO("ldo_vusb", VUSB, vusb_voltages, vusb_idx,
54562306a36Sopenharmony_ci		   MT6358_LDO_VUSB_CON0_0, 0, MT6358_VUSB_ANA_CON0, 0x700),
54662306a36Sopenharmony_ci	MT6358_LDO("ldo_vcamd", VCAMD, vcamd_voltages, vcamd_idx,
54762306a36Sopenharmony_ci		   MT6358_LDO_VCAMD_CON0, 0, MT6358_VCAMD_ANA_CON0, 0xf00),
54862306a36Sopenharmony_ci	MT6358_LDO("ldo_vefuse", VEFUSE, vefuse_voltages, vefuse_idx,
54962306a36Sopenharmony_ci		   MT6358_LDO_VEFUSE_CON0, 0, MT6358_VEFUSE_ANA_CON0, 0xf00),
55062306a36Sopenharmony_ci	MT6358_LDO("ldo_vmch", VMCH, vmch_vemc_voltages, vmch_vemc_idx,
55162306a36Sopenharmony_ci		   MT6358_LDO_VMCH_CON0, 0, MT6358_VMCH_ANA_CON0, 0x700),
55262306a36Sopenharmony_ci	MT6358_LDO("ldo_vcama1", VCAMA1, vcama_voltages, vcama_idx,
55362306a36Sopenharmony_ci		   MT6358_LDO_VCAMA1_CON0, 0, MT6358_VCAMA1_ANA_CON0, 0xf00),
55462306a36Sopenharmony_ci	MT6358_LDO("ldo_vemc", VEMC, vmch_vemc_voltages, vmch_vemc_idx,
55562306a36Sopenharmony_ci		   MT6358_LDO_VEMC_CON0, 0, MT6358_VEMC_ANA_CON0, 0x700),
55662306a36Sopenharmony_ci	MT6358_LDO("ldo_vcn33", VCN33, vcn33_voltages, vcn33_idx,
55762306a36Sopenharmony_ci		   MT6358_LDO_VCN33_CON0_0, 0, MT6358_VCN33_ANA_CON0, 0x300),
55862306a36Sopenharmony_ci	MT6358_LDO("ldo_vcama2", VCAMA2, vcama_voltages, vcama_idx,
55962306a36Sopenharmony_ci		   MT6358_LDO_VCAMA2_CON0, 0, MT6358_VCAMA2_ANA_CON0, 0xf00),
56062306a36Sopenharmony_ci	MT6358_LDO("ldo_vmc", VMC, vmc_voltages, vmc_idx,
56162306a36Sopenharmony_ci		   MT6358_LDO_VMC_CON0, 0, MT6358_VMC_ANA_CON0, 0xf00),
56262306a36Sopenharmony_ci	MT6358_LDO("ldo_vldo28", VLDO28, vldo28_voltages, vldo28_idx,
56362306a36Sopenharmony_ci		   MT6358_LDO_VLDO28_CON0_0, 0,
56462306a36Sopenharmony_ci		   MT6358_VLDO28_ANA_CON0, 0x300),
56562306a36Sopenharmony_ci	MT6358_LDO("ldo_vsim2", VSIM2, vsim_voltages, vsim_idx,
56662306a36Sopenharmony_ci		   MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00),
56762306a36Sopenharmony_ci	MT6358_LDO1("ldo_vsram_proc11", VSRAM_PROC11, 500000, 1293750, 6250,
56862306a36Sopenharmony_ci		    MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON0, 0x7f),
56962306a36Sopenharmony_ci	MT6358_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250,
57062306a36Sopenharmony_ci		    MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON2, 0x7f),
57162306a36Sopenharmony_ci	MT6358_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250,
57262306a36Sopenharmony_ci		    MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON3, 0x7f),
57362306a36Sopenharmony_ci	MT6358_LDO1("ldo_vsram_proc12", VSRAM_PROC12, 500000, 1293750, 6250,
57462306a36Sopenharmony_ci		    MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON1, 0x7f),
57562306a36Sopenharmony_ci};
57662306a36Sopenharmony_ci
57762306a36Sopenharmony_ci/* The array is indexed by id(MT6366_ID_XXX) */
57862306a36Sopenharmony_cistatic const struct mt6358_regulator_info mt6366_regulators[] = {
57962306a36Sopenharmony_ci	MT6366_BUCK("buck_vdram1", VDRAM1, 500000, 2087500, 12500,
58062306a36Sopenharmony_ci		    0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, MT6358_VDRAM1_ANA_CON0, 8),
58162306a36Sopenharmony_ci	MT6366_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250,
58262306a36Sopenharmony_ci		    0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 1),
58362306a36Sopenharmony_ci	MT6366_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
58462306a36Sopenharmony_ci		    0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, MT6358_VPA_ANA_CON0, 3),
58562306a36Sopenharmony_ci	MT6366_BUCK("buck_vproc11", VPROC11, 500000, 1293750, 6250,
58662306a36Sopenharmony_ci		    0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 1),
58762306a36Sopenharmony_ci	MT6366_BUCK("buck_vproc12", VPROC12, 500000, 1293750, 6250,
58862306a36Sopenharmony_ci		    0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 2),
58962306a36Sopenharmony_ci	MT6366_BUCK("buck_vgpu", VGPU, 500000, 1293750, 6250,
59062306a36Sopenharmony_ci		    0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 2),
59162306a36Sopenharmony_ci	MT6366_BUCK("buck_vs2", VS2, 500000, 2087500, 12500,
59262306a36Sopenharmony_ci		    0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, MT6358_VS2_ANA_CON0, 8),
59362306a36Sopenharmony_ci	MT6366_BUCK("buck_vmodem", VMODEM, 500000, 1293750, 6250,
59462306a36Sopenharmony_ci		    0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, MT6358_VMODEM_ANA_CON0, 8),
59562306a36Sopenharmony_ci	MT6366_BUCK("buck_vs1", VS1, 1000000, 2587500, 12500,
59662306a36Sopenharmony_ci		    0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, MT6358_VS1_ANA_CON0, 8),
59762306a36Sopenharmony_ci	MT6366_REG_FIXED("ldo_vrf12", VRF12,
59862306a36Sopenharmony_ci			 MT6358_LDO_VRF12_CON0, 0, 1200000),
59962306a36Sopenharmony_ci	MT6366_REG_FIXED("ldo_vio18", VIO18,
60062306a36Sopenharmony_ci			 MT6358_LDO_VIO18_CON0, 0, 1800000),
60162306a36Sopenharmony_ci	MT6366_REG_FIXED("ldo_vcn18", VCN18, MT6358_LDO_VCN18_CON0, 0, 1800000),
60262306a36Sopenharmony_ci	MT6366_REG_FIXED("ldo_vfe28", VFE28, MT6358_LDO_VFE28_CON0, 0, 2800000),
60362306a36Sopenharmony_ci	MT6366_REG_FIXED("ldo_vcn28", VCN28, MT6358_LDO_VCN28_CON0, 0, 2800000),
60462306a36Sopenharmony_ci	MT6366_REG_FIXED("ldo_vxo22", VXO22, MT6358_LDO_VXO22_CON0, 0, 2200000),
60562306a36Sopenharmony_ci	MT6366_REG_FIXED("ldo_vaux18", VAUX18,
60662306a36Sopenharmony_ci			 MT6358_LDO_VAUX18_CON0, 0, 1800000),
60762306a36Sopenharmony_ci	MT6366_REG_FIXED("ldo_vbif28", VBIF28,
60862306a36Sopenharmony_ci			 MT6358_LDO_VBIF28_CON0, 0, 2800000),
60962306a36Sopenharmony_ci	MT6366_REG_FIXED("ldo_vio28", VIO28, MT6358_LDO_VIO28_CON0, 0, 2800000),
61062306a36Sopenharmony_ci	MT6366_REG_FIXED("ldo_va12", VA12, MT6358_LDO_VA12_CON0, 0, 1200000),
61162306a36Sopenharmony_ci	MT6366_REG_FIXED("ldo_vrf18", VRF18, MT6358_LDO_VRF18_CON0, 0, 1800000),
61262306a36Sopenharmony_ci	MT6366_REG_FIXED("ldo_vaud28", VAUD28,
61362306a36Sopenharmony_ci			 MT6358_LDO_VAUD28_CON0, 0, 2800000),
61462306a36Sopenharmony_ci	MT6366_LDO("ldo_vdram2", VDRAM2, vdram2_voltages, vdram2_idx,
61562306a36Sopenharmony_ci		   MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0x10),
61662306a36Sopenharmony_ci	MT6366_LDO("ldo_vsim1", VSIM1, vsim_voltages, vsim_idx,
61762306a36Sopenharmony_ci		   MT6358_LDO_VSIM1_CON0, 0, MT6358_VSIM1_ANA_CON0, 0xf00),
61862306a36Sopenharmony_ci	MT6366_LDO("ldo_vibr", VIBR, vibr_voltages, vibr_idx,
61962306a36Sopenharmony_ci		   MT6358_LDO_VIBR_CON0, 0, MT6358_VIBR_ANA_CON0, 0xf00),
62062306a36Sopenharmony_ci	MT6366_LDO("ldo_vusb", VUSB, vusb_voltages, vusb_idx,
62162306a36Sopenharmony_ci		   MT6358_LDO_VUSB_CON0_0, 0, MT6358_VUSB_ANA_CON0, 0x700),
62262306a36Sopenharmony_ci	MT6366_LDO("ldo_vefuse", VEFUSE, vefuse_voltages, vefuse_idx,
62362306a36Sopenharmony_ci		   MT6358_LDO_VEFUSE_CON0, 0, MT6358_VEFUSE_ANA_CON0, 0xf00),
62462306a36Sopenharmony_ci	MT6366_LDO("ldo_vmch", VMCH, vmch_vemc_voltages, vmch_vemc_idx,
62562306a36Sopenharmony_ci		   MT6358_LDO_VMCH_CON0, 0, MT6358_VMCH_ANA_CON0, 0x700),
62662306a36Sopenharmony_ci	MT6366_LDO("ldo_vemc", VEMC, vmch_vemc_voltages, vmch_vemc_idx,
62762306a36Sopenharmony_ci		   MT6358_LDO_VEMC_CON0, 0, MT6358_VEMC_ANA_CON0, 0x700),
62862306a36Sopenharmony_ci	MT6366_LDO("ldo_vcn33", VCN33, vcn33_voltages, vcn33_idx,
62962306a36Sopenharmony_ci		   MT6358_LDO_VCN33_CON0_0, 0, MT6358_VCN33_ANA_CON0, 0x300),
63062306a36Sopenharmony_ci	MT6366_LDO("ldo_vmc", VMC, vmc_voltages, vmc_idx,
63162306a36Sopenharmony_ci		   MT6358_LDO_VMC_CON0, 0, MT6358_VMC_ANA_CON0, 0xf00),
63262306a36Sopenharmony_ci	MT6366_LDO("ldo_vsim2", VSIM2, vsim_voltages, vsim_idx,
63362306a36Sopenharmony_ci		   MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00),
63462306a36Sopenharmony_ci	MT6366_LDO1("ldo_vsram_proc11", VSRAM_PROC11, 500000, 1293750, 6250,
63562306a36Sopenharmony_ci		    MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON0, 0x7f),
63662306a36Sopenharmony_ci	MT6366_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250,
63762306a36Sopenharmony_ci		    MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON2, 0x7f),
63862306a36Sopenharmony_ci	MT6366_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250,
63962306a36Sopenharmony_ci		    MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON3, 0x7f),
64062306a36Sopenharmony_ci	MT6366_LDO1("ldo_vsram_proc12", VSRAM_PROC12, 500000, 1293750, 6250,
64162306a36Sopenharmony_ci		    MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON1, 0x7f),
64262306a36Sopenharmony_ci};
64362306a36Sopenharmony_ci
64462306a36Sopenharmony_cistatic int mt6358_sync_vcn33_setting(struct device *dev)
64562306a36Sopenharmony_ci{
64662306a36Sopenharmony_ci	struct mt6397_chip *mt6397 = dev_get_drvdata(dev->parent);
64762306a36Sopenharmony_ci	unsigned int val;
64862306a36Sopenharmony_ci	int ret;
64962306a36Sopenharmony_ci
65062306a36Sopenharmony_ci	/*
65162306a36Sopenharmony_ci	 * VCN33_WIFI and VCN33_BT are two separate enable bits for the same
65262306a36Sopenharmony_ci	 * regulator. They share the same voltage setting and output pin.
65362306a36Sopenharmony_ci	 * Instead of having two potentially conflicting regulators, just have
65462306a36Sopenharmony_ci	 * one VCN33 regulator. Sync the two enable bits and only use one in
65562306a36Sopenharmony_ci	 * the regulator device.
65662306a36Sopenharmony_ci	 */
65762306a36Sopenharmony_ci	ret = regmap_read(mt6397->regmap, MT6358_LDO_VCN33_CON0_1, &val);
65862306a36Sopenharmony_ci	if (ret) {
65962306a36Sopenharmony_ci		dev_err(dev, "Failed to read VCN33_WIFI setting\n");
66062306a36Sopenharmony_ci		return ret;
66162306a36Sopenharmony_ci	}
66262306a36Sopenharmony_ci
66362306a36Sopenharmony_ci	if (!(val & BIT(0)))
66462306a36Sopenharmony_ci		return 0;
66562306a36Sopenharmony_ci
66662306a36Sopenharmony_ci	/* Sync VCN33_WIFI enable status to VCN33_BT */
66762306a36Sopenharmony_ci	ret = regmap_update_bits(mt6397->regmap, MT6358_LDO_VCN33_CON0_0, BIT(0), BIT(0));
66862306a36Sopenharmony_ci	if (ret) {
66962306a36Sopenharmony_ci		dev_err(dev, "Failed to sync VCN33_WIFI setting to VCN33_BT\n");
67062306a36Sopenharmony_ci		return ret;
67162306a36Sopenharmony_ci	}
67262306a36Sopenharmony_ci
67362306a36Sopenharmony_ci	/* Disable VCN33_WIFI */
67462306a36Sopenharmony_ci	ret = regmap_update_bits(mt6397->regmap, MT6358_LDO_VCN33_CON0_1, BIT(0), 0);
67562306a36Sopenharmony_ci	if (ret) {
67662306a36Sopenharmony_ci		dev_err(dev, "Failed to disable VCN33_WIFI\n");
67762306a36Sopenharmony_ci		return ret;
67862306a36Sopenharmony_ci	}
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_ci	return 0;
68162306a36Sopenharmony_ci}
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_cistatic int mt6358_regulator_probe(struct platform_device *pdev)
68462306a36Sopenharmony_ci{
68562306a36Sopenharmony_ci	struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);
68662306a36Sopenharmony_ci	struct regulator_config config = {};
68762306a36Sopenharmony_ci	struct regulator_dev *rdev;
68862306a36Sopenharmony_ci	const struct mt6358_regulator_info *mt6358_info;
68962306a36Sopenharmony_ci	int i, max_regulator, ret;
69062306a36Sopenharmony_ci
69162306a36Sopenharmony_ci	switch (mt6397->chip_id) {
69262306a36Sopenharmony_ci	case MT6358_CHIP_ID:
69362306a36Sopenharmony_ci		max_regulator = MT6358_MAX_REGULATOR;
69462306a36Sopenharmony_ci		mt6358_info = mt6358_regulators;
69562306a36Sopenharmony_ci		break;
69662306a36Sopenharmony_ci	case MT6366_CHIP_ID:
69762306a36Sopenharmony_ci		max_regulator = MT6366_MAX_REGULATOR;
69862306a36Sopenharmony_ci		mt6358_info = mt6366_regulators;
69962306a36Sopenharmony_ci		break;
70062306a36Sopenharmony_ci	default:
70162306a36Sopenharmony_ci		dev_err(&pdev->dev, "unsupported chip ID: %d\n", mt6397->chip_id);
70262306a36Sopenharmony_ci		return -EINVAL;
70362306a36Sopenharmony_ci	}
70462306a36Sopenharmony_ci
70562306a36Sopenharmony_ci	ret = mt6358_sync_vcn33_setting(&pdev->dev);
70662306a36Sopenharmony_ci	if (ret)
70762306a36Sopenharmony_ci		return ret;
70862306a36Sopenharmony_ci
70962306a36Sopenharmony_ci	for (i = 0; i < max_regulator; i++) {
71062306a36Sopenharmony_ci		config.dev = &pdev->dev;
71162306a36Sopenharmony_ci		config.regmap = mt6397->regmap;
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ci		rdev = devm_regulator_register(&pdev->dev,
71462306a36Sopenharmony_ci					       &mt6358_info[i].desc,
71562306a36Sopenharmony_ci					       &config);
71662306a36Sopenharmony_ci		if (IS_ERR(rdev)) {
71762306a36Sopenharmony_ci			dev_err(&pdev->dev, "failed to register %s\n",
71862306a36Sopenharmony_ci				mt6358_info[i].desc.name);
71962306a36Sopenharmony_ci			return PTR_ERR(rdev);
72062306a36Sopenharmony_ci		}
72162306a36Sopenharmony_ci	}
72262306a36Sopenharmony_ci
72362306a36Sopenharmony_ci	return 0;
72462306a36Sopenharmony_ci}
72562306a36Sopenharmony_ci
72662306a36Sopenharmony_cistatic const struct platform_device_id mt6358_platform_ids[] = {
72762306a36Sopenharmony_ci	{"mt6358-regulator", 0},
72862306a36Sopenharmony_ci	{ /* sentinel */ },
72962306a36Sopenharmony_ci};
73062306a36Sopenharmony_ciMODULE_DEVICE_TABLE(platform, mt6358_platform_ids);
73162306a36Sopenharmony_ci
73262306a36Sopenharmony_cistatic struct platform_driver mt6358_regulator_driver = {
73362306a36Sopenharmony_ci	.driver = {
73462306a36Sopenharmony_ci		.name = "mt6358-regulator",
73562306a36Sopenharmony_ci		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
73662306a36Sopenharmony_ci	},
73762306a36Sopenharmony_ci	.probe = mt6358_regulator_probe,
73862306a36Sopenharmony_ci	.id_table = mt6358_platform_ids,
73962306a36Sopenharmony_ci};
74062306a36Sopenharmony_ci
74162306a36Sopenharmony_cimodule_platform_driver(mt6358_regulator_driver);
74262306a36Sopenharmony_ci
74362306a36Sopenharmony_ciMODULE_AUTHOR("Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>");
74462306a36Sopenharmony_ciMODULE_DESCRIPTION("Regulator Driver for MediaTek MT6358 PMIC");
74562306a36Sopenharmony_ciMODULE_LICENSE("GPL");
746