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, ®val); 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, ®val); 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, ®val); 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