brintos

brintos / linux-shallow public Read only

0
0
Text · 27.3 KiB · e4745f6 Raw
746 lines · c
1// SPDX-License-Identifier: GPL-2.02//3// Copyright (c) 2019 MediaTek Inc.4 5#include <linux/mfd/mt6358/registers.h>6#include <linux/mfd/mt6397/core.h>7#include <linux/module.h>8#include <linux/of.h>9#include <linux/platform_device.h>10#include <linux/regmap.h>11#include <linux/regulator/driver.h>12#include <linux/regulator/machine.h>13#include <linux/regulator/mt6358-regulator.h>14#include <linux/regulator/of_regulator.h>15 16#include <dt-bindings/regulator/mediatek,mt6397-regulator.h>17 18/*19 * MT6358 regulators' information20 *21 * @desc: standard fields of regulator description.22 * @qi: Mask for query enable signal status of regulators23 */24struct mt6358_regulator_info {25	struct regulator_desc desc;26	u32 status_reg;27	u32 qi;28	u32 da_vsel_reg;29	u32 da_vsel_mask;30	u32 modeset_reg;31	u32 modeset_mask;32};33 34#define to_regulator_info(x) container_of((x), struct mt6358_regulator_info, desc)35 36#define MT6358_BUCK(match, vreg, supply, min, max, step,	\37		    vosel_mask, _da_vsel_reg, _da_vsel_mask,	\38		    _modeset_reg, _modeset_shift)		\39[MT6358_ID_##vreg] = {	\40	.desc = {	\41		.name = #vreg,	\42		.supply_name = supply,		\43		.of_match = of_match_ptr(match),	\44		.ops = &mt6358_buck_ops,	\45		.type = REGULATOR_VOLTAGE,	\46		.id = MT6358_ID_##vreg,		\47		.owner = THIS_MODULE,		\48		.n_voltages = ((max) - (min)) / (step) + 1,	\49		.min_uV = (min),		\50		.uV_step = (step),		\51		.vsel_reg = MT6358_BUCK_##vreg##_ELR0,	\52		.vsel_mask = vosel_mask,	\53		.enable_reg = MT6358_BUCK_##vreg##_CON0,	\54		.enable_mask = BIT(0),	\55		.of_map_mode = mt6358_map_mode,	\56	},	\57	.status_reg = MT6358_BUCK_##vreg##_DBG1,	\58	.qi = BIT(0),	\59	.da_vsel_reg = _da_vsel_reg,	\60	.da_vsel_mask = _da_vsel_mask,	\61	.modeset_reg = _modeset_reg,	\62	.modeset_mask = BIT(_modeset_shift),	\63}64 65#define MT6358_LDO(match, vreg, supply, volt_ranges, enreg, enbit, vosel, vosel_mask) \66[MT6358_ID_##vreg] = {	\67	.desc = {	\68		.name = #vreg,	\69		.supply_name = supply,		\70		.of_match = of_match_ptr(match),	\71		.ops = &mt6358_volt_table_ops,	\72		.type = REGULATOR_VOLTAGE,	\73		.id = MT6358_ID_##vreg,	\74		.owner = THIS_MODULE,	\75		.n_voltages = ARRAY_SIZE(volt_ranges##_ranges) * 11,	\76		.linear_ranges = volt_ranges##_ranges,		\77		.linear_range_selectors_bitfield = volt_ranges##_selectors,	\78		.n_linear_ranges = ARRAY_SIZE(volt_ranges##_ranges),	\79		.vsel_range_reg = vosel,	\80		.vsel_range_mask = vosel_mask,	\81		.vsel_reg = MT6358_##vreg##_ANA_CON0,	\82		.vsel_mask = GENMASK(3, 0),	\83		.enable_reg = enreg,	\84		.enable_mask = BIT(enbit),	\85	},	\86	.status_reg = MT6358_LDO_##vreg##_CON1,	\87	.qi = BIT(15),	\88}89 90#define MT6358_LDO1(match, vreg, supply, min, max, step,	\91		    _da_vsel_reg, _da_vsel_mask, vosel, vosel_mask)	\92[MT6358_ID_##vreg] = {	\93	.desc = {	\94		.name = #vreg,	\95		.supply_name = supply,		\96		.of_match = of_match_ptr(match),	\97		.ops = &mt6358_volt_range_ops,	\98		.type = REGULATOR_VOLTAGE,	\99		.id = MT6358_ID_##vreg,	\100		.owner = THIS_MODULE,	\101		.n_voltages = ((max) - (min)) / (step) + 1,	\102		.min_uV = (min),		\103		.uV_step = (step),		\104		.vsel_reg = vosel,	\105		.vsel_mask = vosel_mask,	\106		.enable_reg = MT6358_LDO_##vreg##_CON0,	\107		.enable_mask = BIT(0),	\108	},	\109	.da_vsel_reg = _da_vsel_reg,	\110	.da_vsel_mask = _da_vsel_mask,	\111	.status_reg = MT6358_LDO_##vreg##_DBG1,	\112	.qi = BIT(0),	\113}114 115#define MT6358_REG_FIXED(match, vreg, supply, enreg, enbit, volt)	\116[MT6358_ID_##vreg] = {	\117	.desc = {	\118		.name = #vreg,	\119		.supply_name = supply,		\120		.of_match = of_match_ptr(match),	\121		.ops = &mt6358_volt_fixed_ops,	\122		.type = REGULATOR_VOLTAGE,	\123		.id = MT6358_ID_##vreg,	\124		.owner = THIS_MODULE,	\125		.n_voltages = 11,	\126		.vsel_reg = MT6358_##vreg##_ANA_CON0,	\127		.vsel_mask = GENMASK(3, 0),	\128		.enable_reg = enreg,	\129		.enable_mask = BIT(enbit),	\130		.min_uV = volt,	\131		.uV_step = 10000, \132	},	\133	.status_reg = MT6358_LDO_##vreg##_CON1,	\134	.qi = BIT(15),							\135}136 137#define MT6366_BUCK(match, vreg, min, max, step,		\138	vosel_mask, _da_vsel_reg, _da_vsel_mask,	\139	_modeset_reg, _modeset_shift)		\140[MT6366_ID_##vreg] = {	\141	.desc = {	\142		.name = #vreg,	\143		.supply_name = "vsys-" match,		\144		.of_match = of_match_ptr(match),	\145		.ops = &mt6358_buck_ops,	\146		.type = REGULATOR_VOLTAGE,	\147		.id = MT6366_ID_##vreg,		\148		.owner = THIS_MODULE,		\149		.n_voltages = ((max) - (min)) / (step) + 1,	\150		.min_uV = (min),		\151		.uV_step = (step),		\152		.vsel_reg = MT6358_BUCK_##vreg##_ELR0,	\153		.vsel_mask = vosel_mask,	\154		.enable_reg = MT6358_BUCK_##vreg##_CON0,	\155		.enable_mask = BIT(0),	\156		.of_map_mode = mt6358_map_mode,	\157	},	\158	.status_reg = MT6358_BUCK_##vreg##_DBG1,	\159	.qi = BIT(0),	\160	.da_vsel_reg = _da_vsel_reg,	\161	.da_vsel_mask = _da_vsel_mask,	\162	.modeset_reg = _modeset_reg,	\163	.modeset_mask = BIT(_modeset_shift),	\164}165 166#define MT6366_LDO(match, vreg, volt_ranges, supply, enreg, enbit, vosel, vosel_mask) \167[MT6366_ID_##vreg] = {	\168	.desc = {	\169		.name = #vreg,	\170		.supply_name = supply,		\171		.of_match = of_match_ptr(match),	\172		.ops = &mt6358_volt_table_ops,	\173		.type = REGULATOR_VOLTAGE,	\174		.id = MT6366_ID_##vreg,	\175		.owner = THIS_MODULE,	\176		.n_voltages = ARRAY_SIZE(volt_ranges##_ranges) * 11,	\177		.linear_ranges = volt_ranges##_ranges,		\178		.linear_range_selectors_bitfield = volt_ranges##_selectors,	\179		.n_linear_ranges = ARRAY_SIZE(volt_ranges##_ranges),	\180		.vsel_range_reg = vosel,	\181		.vsel_range_mask = vosel_mask,	\182		.vsel_reg = MT6358_##vreg##_ANA_CON0,	\183		.vsel_mask = GENMASK(3, 0),	\184		.enable_reg = enreg,	\185		.enable_mask = BIT(enbit),	\186	},	\187	.status_reg = MT6358_LDO_##vreg##_CON1,	\188	.qi = BIT(15),	\189}190 191#define MT6366_LDO1(match, vreg, supply, min, max, step,	\192		    _da_vsel_reg, _da_vsel_mask, vosel, vosel_mask)	\193[MT6366_ID_##vreg] = {	\194	.desc = {	\195		.name = #vreg,	\196		.supply_name = supply,		\197		.of_match = of_match_ptr(match),	\198		.ops = &mt6358_volt_range_ops,	\199		.type = REGULATOR_VOLTAGE,	\200		.id = MT6366_ID_##vreg,	\201		.owner = THIS_MODULE,	\202		.n_voltages = ((max) - (min)) / (step) + 1,	\203		.min_uV = (min),		\204		.uV_step = (step),		\205		.vsel_reg = vosel,	\206		.vsel_mask = vosel_mask,	\207		.enable_reg = MT6358_LDO_##vreg##_CON0,	\208		.enable_mask = BIT(0),	\209	},	\210	.da_vsel_reg = _da_vsel_reg,	\211	.da_vsel_mask = _da_vsel_mask,	\212	.status_reg = MT6358_LDO_##vreg##_DBG1,	\213	.qi = BIT(0),	\214}215 216#define MT6366_REG_FIXED(match, vreg, supply, enreg, enbit, volt)	\217[MT6366_ID_##vreg] = {	\218	.desc = {	\219		.name = #vreg,	\220		.supply_name = supply,		\221		.of_match = of_match_ptr(match),	\222		.ops = &mt6358_volt_fixed_ops,	\223		.type = REGULATOR_VOLTAGE,	\224		.id = MT6366_ID_##vreg,	\225		.owner = THIS_MODULE,	\226		.n_voltages = 11,	\227		.vsel_reg = MT6358_##vreg##_ANA_CON0,	\228		.vsel_mask = GENMASK(3, 0),	\229		.enable_reg = enreg,	\230		.enable_mask = BIT(enbit),	\231		.min_uV = volt,	\232		.uV_step = 10000, \233	},	\234	.status_reg = MT6358_LDO_##vreg##_CON1,	\235	.qi = BIT(15),							\236}237 238 239/* VDRAM2 voltage selector not shown in datasheet */240static const unsigned int vdram2_selectors[] = { 0, 12 };241static const struct linear_range vdram2_ranges[] = {242	REGULATOR_LINEAR_RANGE(600000, 0, 10, 10000),243	REGULATOR_LINEAR_RANGE(1800000, 0, 10, 10000),244};245 246static const unsigned int vsim_selectors[] = { 3, 4, 8, 11, 12 };247static const struct linear_range vsim_ranges[] = {248	REGULATOR_LINEAR_RANGE(1700000, 0, 10, 10000),249	REGULATOR_LINEAR_RANGE(1800000, 0, 10, 10000),250	REGULATOR_LINEAR_RANGE(2700000, 0, 10, 10000),251	REGULATOR_LINEAR_RANGE(3000000, 0, 10, 10000),252	REGULATOR_LINEAR_RANGE(3100000, 0, 10, 10000),253};254 255static const unsigned int vibr_selectors[] = { 0, 1, 2, 4, 5, 9, 11, 13 };256static const struct linear_range vibr_ranges[] = {257	REGULATOR_LINEAR_RANGE(1200000, 0, 10, 10000),258	REGULATOR_LINEAR_RANGE(1300000, 0, 10, 10000),259	REGULATOR_LINEAR_RANGE(1500000, 0, 10, 10000),260	REGULATOR_LINEAR_RANGE(1800000, 0, 10, 10000),261	REGULATOR_LINEAR_RANGE(2000000, 0, 10, 10000),262	REGULATOR_LINEAR_RANGE(2800000, 0, 10, 10000),263	REGULATOR_LINEAR_RANGE(3000000, 0, 10, 10000),264	REGULATOR_LINEAR_RANGE(3300000, 0, 10, 10000),265};266 267/* VUSB voltage selector not shown in datasheet */268static const unsigned int vusb_selectors[] = { 3, 4 };269static const struct linear_range vusb_ranges[] = {270	REGULATOR_LINEAR_RANGE(3000000, 0, 10, 10000),271	REGULATOR_LINEAR_RANGE(3100000, 0, 10, 10000),272};273 274static const unsigned int vcamd_selectors[] = { 3, 4, 5, 6, 7, 9, 12 };275static const struct linear_range vcamd_ranges[] = {276	REGULATOR_LINEAR_RANGE(900000, 0, 10, 10000),277	REGULATOR_LINEAR_RANGE(1000000, 0, 10, 10000),278	REGULATOR_LINEAR_RANGE(1100000, 0, 10, 10000),279	REGULATOR_LINEAR_RANGE(1200000, 0, 10, 10000),280	REGULATOR_LINEAR_RANGE(1300000, 0, 10, 10000),281	REGULATOR_LINEAR_RANGE(1500000, 0, 10, 10000),282	REGULATOR_LINEAR_RANGE(1800000, 0, 10, 10000),283};284 285static const unsigned int vefuse_selectors[] = { 11, 12, 13 };286static const struct linear_range vefuse_ranges[] = {287	REGULATOR_LINEAR_RANGE(1700000, 0, 10, 10000),288	REGULATOR_LINEAR_RANGE(1800000, 0, 10, 10000),289	REGULATOR_LINEAR_RANGE(1900000, 0, 10, 10000),290};291 292static const unsigned int vmch_vemc_selectors[] = { 2, 3, 5 };293static const struct linear_range vmch_vemc_ranges[] = {294	REGULATOR_LINEAR_RANGE(2900000, 0, 10, 10000),295	REGULATOR_LINEAR_RANGE(3000000, 0, 10, 10000),296	REGULATOR_LINEAR_RANGE(3300000, 0, 10, 10000),297};298 299static const unsigned int vcama_selectors[] = { 0, 7, 9, 10, 11, 12 };300static const struct linear_range vcama_ranges[] = {301	REGULATOR_LINEAR_RANGE(1800000, 0, 10, 10000),302	REGULATOR_LINEAR_RANGE(2500000, 0, 10, 10000),303	REGULATOR_LINEAR_RANGE(2700000, 0, 10, 10000),304	REGULATOR_LINEAR_RANGE(2800000, 0, 10, 10000),305	REGULATOR_LINEAR_RANGE(2900000, 0, 10, 10000),306	REGULATOR_LINEAR_RANGE(3000000, 0, 10, 10000),307};308 309static const unsigned int vcn33_selectors[] = { 1, 2, 3 };310static const struct linear_range vcn33_ranges[] = {311	REGULATOR_LINEAR_RANGE(3300000, 0, 10, 10000),312	REGULATOR_LINEAR_RANGE(3400000, 0, 10, 10000),313	REGULATOR_LINEAR_RANGE(3500000, 0, 10, 10000),314};315 316static const unsigned int vmc_selectors[] = { 4, 10, 11, 13 };317static const struct linear_range vmc_ranges[] = {318	REGULATOR_LINEAR_RANGE(1800000, 0, 10, 10000),319	REGULATOR_LINEAR_RANGE(2900000, 0, 10, 10000),320	REGULATOR_LINEAR_RANGE(3000000, 0, 10, 10000),321	REGULATOR_LINEAR_RANGE(3300000, 0, 10, 10000),322};323 324static const unsigned int vldo28_selectors[] = { 1, 3 };325static const struct linear_range vldo28_ranges[] = {326	REGULATOR_LINEAR_RANGE(2800000, 0, 10, 10000),327	REGULATOR_LINEAR_RANGE(3000000, 0, 10, 10000),328};329 330static const unsigned int mt6366_vmddr_selectors[] = { 0, 1, 2, 3, 4, 5, 6, 7, 9, 12 };331static const struct linear_range mt6366_vmddr_ranges[] = {332	REGULATOR_LINEAR_RANGE(600000, 0, 10, 10000),333	REGULATOR_LINEAR_RANGE(700000, 0, 10, 10000),334	REGULATOR_LINEAR_RANGE(800000, 0, 10, 10000),335	REGULATOR_LINEAR_RANGE(900000, 0, 10, 10000),336	REGULATOR_LINEAR_RANGE(1000000, 0, 10, 10000),337	REGULATOR_LINEAR_RANGE(1100000, 0, 10, 10000),338	REGULATOR_LINEAR_RANGE(1200000, 0, 10, 10000),339	REGULATOR_LINEAR_RANGE(1300000, 0, 10, 10000),340	REGULATOR_LINEAR_RANGE(1500000, 0, 10, 10000),341	REGULATOR_LINEAR_RANGE(1800000, 0, 10, 10000),342};343 344static const unsigned int mt6366_vcn18_vm18_selectors[] = {345	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };346static const struct linear_range mt6366_vcn18_vm18_ranges[] = {347	REGULATOR_LINEAR_RANGE(600000, 0, 10, 10000),348	REGULATOR_LINEAR_RANGE(700000, 0, 10, 10000),349	REGULATOR_LINEAR_RANGE(800000, 0, 10, 10000),350	REGULATOR_LINEAR_RANGE(900000, 0, 10, 10000),351	REGULATOR_LINEAR_RANGE(1000000, 0, 10, 10000),352	REGULATOR_LINEAR_RANGE(1100000, 0, 10, 10000),353	REGULATOR_LINEAR_RANGE(1200000, 0, 10, 10000),354	REGULATOR_LINEAR_RANGE(1300000, 0, 10, 10000),355	REGULATOR_LINEAR_RANGE(1400000, 0, 10, 10000),356	REGULATOR_LINEAR_RANGE(1500000, 0, 10, 10000),357	REGULATOR_LINEAR_RANGE(1600000, 0, 10, 10000),358	REGULATOR_LINEAR_RANGE(1700000, 0, 10, 10000),359	REGULATOR_LINEAR_RANGE(1800000, 0, 10, 10000),360	REGULATOR_LINEAR_RANGE(1900000, 0, 10, 10000),361	REGULATOR_LINEAR_RANGE(2000000, 0, 10, 10000),362	REGULATOR_LINEAR_RANGE(2100000, 0, 10, 10000),363};364 365static unsigned int mt6358_map_mode(unsigned int mode)366{367	return mode == MT6397_BUCK_MODE_AUTO ?368		REGULATOR_MODE_NORMAL : REGULATOR_MODE_FAST;369}370 371static int mt6358_get_buck_voltage_sel(struct regulator_dev *rdev)372{373	const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);374	int ret, regval;375 376	ret = regmap_read(rdev->regmap, info->da_vsel_reg, &regval);377	if (ret != 0) {378		dev_err(&rdev->dev,379			"Failed to get mt6358 Buck %s vsel reg: %d\n",380			info->desc.name, ret);381		return ret;382	}383 384	ret = (regval & info->da_vsel_mask) >> (ffs(info->da_vsel_mask) - 1);385 386	return ret;387}388 389static int mt6358_get_status(struct regulator_dev *rdev)390{391	const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);392	int ret;393	u32 regval;394 395	ret = regmap_read(rdev->regmap, info->status_reg, &regval);396	if (ret != 0) {397		dev_info(&rdev->dev, "Failed to get enable reg: %d\n", ret);398		return ret;399	}400 401	return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF;402}403 404static int mt6358_regulator_set_mode(struct regulator_dev *rdev,405				     unsigned int mode)406{407	const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);408	int val;409 410	switch (mode) {411	case REGULATOR_MODE_FAST:412		val = MT6397_BUCK_MODE_FORCE_PWM;413		break;414	case REGULATOR_MODE_NORMAL:415		val = MT6397_BUCK_MODE_AUTO;416		break;417	default:418		return -EINVAL;419	}420 421	dev_dbg(&rdev->dev, "mt6358 buck set_mode %#x, %#x, %#x\n",422		info->modeset_reg, info->modeset_mask, val);423 424	val <<= ffs(info->modeset_mask) - 1;425 426	return regmap_update_bits(rdev->regmap, info->modeset_reg,427				  info->modeset_mask, val);428}429 430static unsigned int mt6358_regulator_get_mode(struct regulator_dev *rdev)431{432	const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);433	int ret, regval;434 435	ret = regmap_read(rdev->regmap, info->modeset_reg, &regval);436	if (ret != 0) {437		dev_err(&rdev->dev,438			"Failed to get mt6358 buck mode: %d\n", ret);439		return ret;440	}441 442	switch ((regval & info->modeset_mask) >> (ffs(info->modeset_mask) - 1)) {443	case MT6397_BUCK_MODE_AUTO:444		return REGULATOR_MODE_NORMAL;445	case MT6397_BUCK_MODE_FORCE_PWM:446		return REGULATOR_MODE_FAST;447	default:448		return -EINVAL;449	}450}451 452static const struct regulator_ops mt6358_buck_ops = {453	.list_voltage = regulator_list_voltage_linear,454	.map_voltage = regulator_map_voltage_linear,455	.set_voltage_sel = regulator_set_voltage_sel_regmap,456	.get_voltage_sel = mt6358_get_buck_voltage_sel,457	.set_voltage_time_sel = regulator_set_voltage_time_sel,458	.enable = regulator_enable_regmap,459	.disable = regulator_disable_regmap,460	.is_enabled = regulator_is_enabled_regmap,461	.get_status = mt6358_get_status,462	.set_mode = mt6358_regulator_set_mode,463	.get_mode = mt6358_regulator_get_mode,464};465 466static const struct regulator_ops mt6358_volt_range_ops = {467	.list_voltage = regulator_list_voltage_linear,468	.map_voltage = regulator_map_voltage_linear,469	.set_voltage_sel = regulator_set_voltage_sel_regmap,470	.get_voltage_sel = mt6358_get_buck_voltage_sel,471	.set_voltage_time_sel = regulator_set_voltage_time_sel,472	.enable = regulator_enable_regmap,473	.disable = regulator_disable_regmap,474	.is_enabled = regulator_is_enabled_regmap,475	.get_status = mt6358_get_status,476};477 478static const struct regulator_ops mt6358_volt_table_ops = {479	.list_voltage = regulator_list_voltage_pickable_linear_range,480	.map_voltage = regulator_map_voltage_pickable_linear_range,481	.set_voltage_sel = regulator_set_voltage_sel_pickable_regmap,482	.get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,483	.set_voltage_time_sel = regulator_set_voltage_time_sel,484	.enable = regulator_enable_regmap,485	.disable = regulator_disable_regmap,486	.is_enabled = regulator_is_enabled_regmap,487	.get_status = mt6358_get_status,488};489 490/* "Fixed" LDOs with output voltage calibration +0 ~ +10 mV */491static const struct regulator_ops mt6358_volt_fixed_ops = {492	.list_voltage = regulator_list_voltage_linear,493	.map_voltage = regulator_map_voltage_linear,494	.set_voltage_sel = regulator_set_voltage_sel_regmap,495	.get_voltage_sel = mt6358_get_buck_voltage_sel,496	.set_voltage_time_sel = regulator_set_voltage_time_sel,497	.enable = regulator_enable_regmap,498	.disable = regulator_disable_regmap,499	.is_enabled = regulator_is_enabled_regmap,500	.get_status = mt6358_get_status,501};502 503/* The array is indexed by id(MT6358_ID_XXX) */504static const struct mt6358_regulator_info mt6358_regulators[] = {505	MT6358_BUCK("buck_vdram1", VDRAM1, "vsys-vdram1", 500000, 2087500, 12500,506		    0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, MT6358_VDRAM1_ANA_CON0, 8),507	MT6358_BUCK("buck_vcore", VCORE, "vsys-vcore", 500000, 1293750, 6250,508		    0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 1),509	MT6358_BUCK("buck_vpa", VPA, "vsys-vpa", 500000, 3650000, 50000,510		    0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, MT6358_VPA_ANA_CON0, 3),511	MT6358_BUCK("buck_vproc11", VPROC11, "vsys-vproc11", 500000, 1293750, 6250,512		    0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 1),513	MT6358_BUCK("buck_vproc12", VPROC12, "vsys-vproc12", 500000, 1293750, 6250,514		    0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 2),515	MT6358_BUCK("buck_vgpu", VGPU, "vsys-vgpu", 500000, 1293750, 6250,516		    0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 2),517	MT6358_BUCK("buck_vs2", VS2, "vsys-vs2", 500000, 2087500, 12500,518		    0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, MT6358_VS2_ANA_CON0, 8),519	MT6358_BUCK("buck_vmodem", VMODEM, "vsys-vmodem", 500000, 1293750, 6250,520		    0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, MT6358_VMODEM_ANA_CON0, 8),521	MT6358_BUCK("buck_vs1", VS1, "vsys-vs1", 1000000, 2587500, 12500,522		    0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, MT6358_VS1_ANA_CON0, 8),523	MT6358_REG_FIXED("ldo_vrf12", VRF12, "vs2-ldo2", MT6358_LDO_VRF12_CON0, 0, 1200000),524	MT6358_REG_FIXED("ldo_vio18", VIO18, "vs1-ldo1", MT6358_LDO_VIO18_CON0, 0, 1800000),525	MT6358_REG_FIXED("ldo_vcamio", VCAMIO, "vs1-ldo1", MT6358_LDO_VCAMIO_CON0, 0, 1800000),526	MT6358_REG_FIXED("ldo_vcn18", VCN18, "vs1-ldo1", MT6358_LDO_VCN18_CON0, 0, 1800000),527	MT6358_REG_FIXED("ldo_vfe28", VFE28, "vsys-ldo1", MT6358_LDO_VFE28_CON0, 0, 2800000),528	MT6358_REG_FIXED("ldo_vcn28", VCN28, "vsys-ldo1", MT6358_LDO_VCN28_CON0, 0, 2800000),529	MT6358_REG_FIXED("ldo_vxo22", VXO22, "vsys-ldo1", MT6358_LDO_VXO22_CON0, 0, 2200000),530	MT6358_REG_FIXED("ldo_vaux18", VAUX18, "vsys-ldo1", MT6358_LDO_VAUX18_CON0, 0, 1800000),531	MT6358_REG_FIXED("ldo_vbif28", VBIF28, "vsys-ldo1", MT6358_LDO_VBIF28_CON0, 0, 2800000),532	MT6358_REG_FIXED("ldo_vio28", VIO28, "vsys-ldo2", MT6358_LDO_VIO28_CON0, 0, 2800000),533	MT6358_REG_FIXED("ldo_va12", VA12, "vs2-ldo2", MT6358_LDO_VA12_CON0, 0, 1200000),534	MT6358_REG_FIXED("ldo_vrf18", VRF18, "vs1-ldo1", MT6358_LDO_VRF18_CON0, 0, 1800000),535	MT6358_REG_FIXED("ldo_vaud28", VAUD28, "vsys-ldo1", MT6358_LDO_VAUD28_CON0, 0, 2800000),536	MT6358_LDO("ldo_vdram2", VDRAM2, "vs2-ldo1", vdram2,537		   MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0xf),538	MT6358_LDO("ldo_vsim1", VSIM1, "vsys-ldo1", vsim,539		   MT6358_LDO_VSIM1_CON0, 0, MT6358_VSIM1_ANA_CON0, 0xf00),540	MT6358_LDO("ldo_vibr", VIBR, "vsys-ldo3", vibr,541		   MT6358_LDO_VIBR_CON0, 0, MT6358_VIBR_ANA_CON0, 0xf00),542	MT6358_LDO("ldo_vusb", VUSB, "vsys-ldo1", vusb,543		   MT6358_LDO_VUSB_CON0_0, 0, MT6358_VUSB_ANA_CON0, 0x700),544	MT6358_LDO("ldo_vcamd", VCAMD, "vs2-ldo4", vcamd,545		   MT6358_LDO_VCAMD_CON0, 0, MT6358_VCAMD_ANA_CON0, 0xf00),546	MT6358_LDO("ldo_vefuse", VEFUSE, "vs1-ldo1", vefuse,547		   MT6358_LDO_VEFUSE_CON0, 0, MT6358_VEFUSE_ANA_CON0, 0xf00),548	MT6358_LDO("ldo_vmch", VMCH, "vsys-ldo2", vmch_vemc,549		   MT6358_LDO_VMCH_CON0, 0, MT6358_VMCH_ANA_CON0, 0x700),550	MT6358_LDO("ldo_vcama1", VCAMA1, "vsys-ldo3", vcama,551		   MT6358_LDO_VCAMA1_CON0, 0, MT6358_VCAMA1_ANA_CON0, 0xf00),552	MT6358_LDO("ldo_vemc", VEMC, "vsys-ldo2", vmch_vemc,553		   MT6358_LDO_VEMC_CON0, 0, MT6358_VEMC_ANA_CON0, 0x700),554	MT6358_LDO("ldo_vcn33", VCN33, "vsys-ldo3", vcn33,555		   MT6358_LDO_VCN33_CON0_0, 0, MT6358_VCN33_ANA_CON0, 0x300),556	MT6358_LDO("ldo_vcama2", VCAMA2, "vsys-ldo3", vcama,557		   MT6358_LDO_VCAMA2_CON0, 0, MT6358_VCAMA2_ANA_CON0, 0xf00),558	MT6358_LDO("ldo_vmc", VMC, "vsys-ldo2", vmc,559		   MT6358_LDO_VMC_CON0, 0, MT6358_VMC_ANA_CON0, 0xf00),560	MT6358_LDO("ldo_vldo28", VLDO28, "vsys-ldo2", vldo28,561		   MT6358_LDO_VLDO28_CON0_0, 0,562		   MT6358_VLDO28_ANA_CON0, 0x300),563	MT6358_LDO("ldo_vsim2", VSIM2, "vsys-ldo2", vsim,564		   MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00),565	MT6358_LDO1("ldo_vsram_proc11", VSRAM_PROC11, "vs2-ldo3", 500000, 1293750, 6250,566		    MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON0, 0x7f),567	MT6358_LDO1("ldo_vsram_others", VSRAM_OTHERS, "vs2-ldo3", 500000, 1293750, 6250,568		    MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON2, 0x7f),569	MT6358_LDO1("ldo_vsram_gpu", VSRAM_GPU, "vs2-ldo3", 500000, 1293750, 6250,570		    MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON3, 0x7f),571	MT6358_LDO1("ldo_vsram_proc12", VSRAM_PROC12, "vs2-ldo3", 500000, 1293750, 6250,572		    MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON1, 0x7f),573};574 575/* The array is indexed by id(MT6366_ID_XXX) */576static const struct mt6358_regulator_info mt6366_regulators[] = {577	MT6366_BUCK("vdram1", VDRAM1, 500000, 2087500, 12500,578		    0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, MT6358_VDRAM1_ANA_CON0, 8),579	MT6366_BUCK("vcore", VCORE, 500000, 1293750, 6250,580		    0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 1),581	MT6366_BUCK("vpa", VPA, 500000, 3650000, 50000,582		    0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, MT6358_VPA_ANA_CON0, 3),583	MT6366_BUCK("vproc11", VPROC11, 500000, 1293750, 6250,584		    0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 1),585	MT6366_BUCK("vproc12", VPROC12, 500000, 1293750, 6250,586		    0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 2),587	MT6366_BUCK("vgpu", VGPU, 500000, 1293750, 6250,588		    0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 2),589	MT6366_BUCK("vs2", VS2, 500000, 2087500, 12500,590		    0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, MT6358_VS2_ANA_CON0, 8),591	MT6366_BUCK("vmodem", VMODEM, 500000, 1293750, 6250,592		    0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, MT6358_VMODEM_ANA_CON0, 8),593	MT6366_BUCK("vs1", VS1, 1000000, 2587500, 12500,594		    0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, MT6358_VS1_ANA_CON0, 8),595	MT6366_REG_FIXED("vrf12", VRF12, "vs2-ldo2", MT6358_LDO_VRF12_CON0, 0, 1200000),596	MT6366_REG_FIXED("vio18", VIO18, "vs1-ldo1", MT6358_LDO_VIO18_CON0, 0, 1800000),597	MT6366_REG_FIXED("vfe28", VFE28, "vsys-ldo1", MT6358_LDO_VFE28_CON0, 0, 2800000),598	MT6366_REG_FIXED("vcn28", VCN28, "vsys-ldo1", MT6358_LDO_VCN28_CON0, 0, 2800000),599	MT6366_REG_FIXED("vxo22", VXO22, "vsys-ldo1", MT6358_LDO_VXO22_CON0, 0, 2200000),600	MT6366_REG_FIXED("vaux18", VAUX18, "vsys-ldo1", MT6358_LDO_VAUX18_CON0, 0, 1800000),601	MT6366_REG_FIXED("vbif28", VBIF28, "vsys-ldo1", MT6358_LDO_VBIF28_CON0, 0, 2800000),602	MT6366_REG_FIXED("vio28", VIO28, "vsys-ldo2", MT6358_LDO_VIO28_CON0, 0, 2800000),603	MT6366_REG_FIXED("va12", VA12, "vs2-ldo2", MT6358_LDO_VA12_CON0, 0, 1200000),604	MT6366_REG_FIXED("vrf18", VRF18, "vs1-ldo1", MT6358_LDO_VRF18_CON0, 0, 1800000),605	MT6366_REG_FIXED("vaud28", VAUD28, "vsys-ldo1", MT6358_LDO_VAUD28_CON0, 0, 2800000),606	MT6366_LDO("vdram2", VDRAM2, vdram2, "vs2-ldo1",607		   MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0x10),608	MT6366_LDO("vsim1", VSIM1, vsim, "vsys-ldo1",609		   MT6358_LDO_VSIM1_CON0, 0, MT6358_VSIM1_ANA_CON0, 0xf00),610	MT6366_LDO("vibr", VIBR, vibr, "vsys-ldo3",611		   MT6358_LDO_VIBR_CON0, 0, MT6358_VIBR_ANA_CON0, 0xf00),612	MT6366_LDO("vusb", VUSB, vusb, "vsys-ldo1",613		   MT6358_LDO_VUSB_CON0_0, 0, MT6358_VUSB_ANA_CON0, 0x700),614	MT6366_LDO("vefuse", VEFUSE, vefuse, "vs1-ldo1",615		   MT6358_LDO_VEFUSE_CON0, 0, MT6358_VEFUSE_ANA_CON0, 0xf00),616	MT6366_LDO("vmch", VMCH, vmch_vemc, "vsys-ldo2",617		   MT6358_LDO_VMCH_CON0, 0, MT6358_VMCH_ANA_CON0, 0x700),618	MT6366_LDO("vemc", VEMC, vmch_vemc, "vsys-ldo3",619		   MT6358_LDO_VEMC_CON0, 0, MT6358_VEMC_ANA_CON0, 0x700),620	MT6366_LDO("vcn33", VCN33, vcn33, "vsys-ldo3",621		   MT6358_LDO_VCN33_CON0_0, 0, MT6358_VCN33_ANA_CON0, 0x300),622	MT6366_LDO("vmc", VMC, vmc, "vsys-ldo2",623		   MT6358_LDO_VMC_CON0, 0, MT6358_VMC_ANA_CON0, 0xf00),624	MT6366_LDO("vsim2", VSIM2, vsim, "vsys-ldo2",625		   MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00),626	MT6366_LDO("vcn18", VCN18, mt6366_vcn18_vm18, "vs1-ldo1",627		   MT6358_LDO_VCN18_CON0, 0, MT6358_VCN18_ANA_CON0, 0xf00),628	MT6366_LDO("vm18", VM18, mt6366_vcn18_vm18, "vs1-ldo1",629		   MT6358_LDO_VM18_CON0, 0, MT6358_VM18_ANA_CON0, 0xf00),630	MT6366_LDO("vmddr", VMDDR, mt6366_vmddr, "vs2-ldo1",631		   MT6358_LDO_VMDDR_CON0, 0, MT6358_VMDDR_ANA_CON0, 0xf00),632	MT6366_LDO1("vsram-proc11", VSRAM_PROC11, "vs2-ldo3", 500000, 1293750, 6250,633		    MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON0, 0x7f),634	MT6366_LDO1("vsram-others", VSRAM_OTHERS, "vs2-ldo3", 500000, 1293750, 6250,635		    MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON2, 0x7f),636	MT6366_LDO1("vsram-gpu", VSRAM_GPU, "vs2-ldo3", 500000, 1293750, 6250,637		    MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON3, 0x7f),638	MT6366_LDO1("vsram-proc12", VSRAM_PROC12, "vs2-ldo3", 500000, 1293750, 6250,639		    MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON1, 0x7f),640	MT6366_LDO1("vsram-core", VSRAM_CORE, "vs2-ldo3", 500000, 1293750, 6250,641		    MT6358_LDO_VSRAM_CORE_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON5, 0x7f),642};643 644static int mt6358_sync_vcn33_setting(struct device *dev)645{646	struct mt6397_chip *mt6397 = dev_get_drvdata(dev->parent);647	unsigned int val;648	int ret;649 650	/*651	 * VCN33_WIFI and VCN33_BT are two separate enable bits for the same652	 * regulator. They share the same voltage setting and output pin.653	 * Instead of having two potentially conflicting regulators, just have654	 * one VCN33 regulator. Sync the two enable bits and only use one in655	 * the regulator device.656	 */657	ret = regmap_read(mt6397->regmap, MT6358_LDO_VCN33_CON0_1, &val);658	if (ret) {659		dev_err(dev, "Failed to read VCN33_WIFI setting\n");660		return ret;661	}662 663	if (!(val & BIT(0)))664		return 0;665 666	/* Sync VCN33_WIFI enable status to VCN33_BT */667	ret = regmap_update_bits(mt6397->regmap, MT6358_LDO_VCN33_CON0_0, BIT(0), BIT(0));668	if (ret) {669		dev_err(dev, "Failed to sync VCN33_WIFI setting to VCN33_BT\n");670		return ret;671	}672 673	/* Disable VCN33_WIFI */674	ret = regmap_update_bits(mt6397->regmap, MT6358_LDO_VCN33_CON0_1, BIT(0), 0);675	if (ret) {676		dev_err(dev, "Failed to disable VCN33_WIFI\n");677		return ret;678	}679 680	return 0;681}682 683static int mt6358_regulator_probe(struct platform_device *pdev)684{685	struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);686	struct regulator_config config = {};687	struct regulator_dev *rdev;688	const struct mt6358_regulator_info *mt6358_info;689	int i, max_regulator, ret;690 691	switch (mt6397->chip_id) {692	case MT6358_CHIP_ID:693		max_regulator = MT6358_MAX_REGULATOR;694		mt6358_info = mt6358_regulators;695		break;696	case MT6366_CHIP_ID:697		max_regulator = MT6366_MAX_REGULATOR;698		mt6358_info = mt6366_regulators;699		break;700	default:701		dev_err(&pdev->dev, "unsupported chip ID: %d\n", mt6397->chip_id);702		return -EINVAL;703	}704 705	ret = mt6358_sync_vcn33_setting(&pdev->dev);706	if (ret)707		return ret;708 709	for (i = 0; i < max_regulator; i++) {710		config.dev = &pdev->dev;711		config.regmap = mt6397->regmap;712 713		rdev = devm_regulator_register(&pdev->dev,714					       &mt6358_info[i].desc,715					       &config);716		if (IS_ERR(rdev)) {717			dev_err(&pdev->dev, "failed to register %s\n",718				mt6358_info[i].desc.name);719			return PTR_ERR(rdev);720		}721	}722 723	return 0;724}725 726static const struct platform_device_id mt6358_platform_ids[] = {727	{"mt6358-regulator", 0},728	{ /* sentinel */ },729};730MODULE_DEVICE_TABLE(platform, mt6358_platform_ids);731 732static struct platform_driver mt6358_regulator_driver = {733	.driver = {734		.name = "mt6358-regulator",735		.probe_type = PROBE_PREFER_ASYNCHRONOUS,736	},737	.probe = mt6358_regulator_probe,738	.id_table = mt6358_platform_ids,739};740 741module_platform_driver(mt6358_regulator_driver);742 743MODULE_AUTHOR("Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>");744MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6358 PMIC");745MODULE_LICENSE("GPL");746