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