Blame view
drivers/regulator/mt6397-regulator.c
12.8 KB
fe669cb95 regulator: mt63xx... |
1 2 3 4 |
// SPDX-License-Identifier: GPL-2.0 // // Copyright (c) 2014 MediaTek Inc. // Author: Flora Fu <flora.fu@mediatek.com> |
0425e2420 regulator: mt6397... |
5 6 7 8 9 10 11 12 13 14 15 |
#include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/regmap.h> #include <linux/mfd/mt6397/core.h> #include <linux/mfd/mt6397/registers.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> #include <linux/regulator/mt6397-regulator.h> #include <linux/regulator/of_regulator.h> |
1c537b2d7 regulator: mt6397... |
16 |
#include <dt-bindings/regulator/mediatek,mt6397-regulator.h> |
056925132 regulator: mt6397... |
17 |
|
0425e2420 regulator: mt6397... |
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
/* * MT6397 regulators' information * * @desc: standard fields of regulator description. * @qi: Mask for query enable signal status of regulators * @vselon_reg: Register sections for hardware control mode of bucks * @vselctrl_reg: Register for controlling the buck control mode. * @vselctrl_mask: Mask for query buck's voltage control mode. */ struct mt6397_regulator_info { struct regulator_desc desc; u32 qi; u32 vselon_reg; u32 vselctrl_reg; u32 vselctrl_mask; |
056925132 regulator: mt6397... |
33 34 35 |
u32 modeset_reg; u32 modeset_mask; u32 modeset_shift; |
0425e2420 regulator: mt6397... |
36 37 38 |
}; #define MT6397_BUCK(match, vreg, min, max, step, volt_ranges, enreg, \ |
056925132 regulator: mt6397... |
39 40 |
vosel, vosel_mask, voselon, vosel_ctrl, _modeset_reg, \ _modeset_shift) \ |
0425e2420 regulator: mt6397... |
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
[MT6397_ID_##vreg] = { \ .desc = { \ .name = #vreg, \ .of_match = of_match_ptr(match), \ .ops = &mt6397_volt_range_ops, \ .type = REGULATOR_VOLTAGE, \ .id = MT6397_ID_##vreg, \ .owner = THIS_MODULE, \ .n_voltages = (max - min)/step + 1, \ .linear_ranges = volt_ranges, \ .n_linear_ranges = ARRAY_SIZE(volt_ranges), \ .vsel_reg = vosel, \ .vsel_mask = vosel_mask, \ .enable_reg = enreg, \ .enable_mask = BIT(0), \ |
8096236db regulator: mt6397... |
56 |
.of_map_mode = mt6397_map_mode, \ |
0425e2420 regulator: mt6397... |
57 58 59 60 61 |
}, \ .qi = BIT(13), \ .vselon_reg = voselon, \ .vselctrl_reg = vosel_ctrl, \ .vselctrl_mask = BIT(1), \ |
056925132 regulator: mt6397... |
62 63 64 |
.modeset_reg = _modeset_reg, \ .modeset_mask = BIT(_modeset_shift), \ .modeset_shift = _modeset_shift \ |
0425e2420 regulator: mt6397... |
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
} #define MT6397_LDO(match, vreg, ldo_volt_table, enreg, enbit, vosel, \ vosel_mask) \ [MT6397_ID_##vreg] = { \ .desc = { \ .name = #vreg, \ .of_match = of_match_ptr(match), \ .ops = &mt6397_volt_table_ops, \ .type = REGULATOR_VOLTAGE, \ .id = MT6397_ID_##vreg, \ .owner = THIS_MODULE, \ .n_voltages = ARRAY_SIZE(ldo_volt_table), \ .volt_table = ldo_volt_table, \ .vsel_reg = vosel, \ .vsel_mask = vosel_mask, \ .enable_reg = enreg, \ .enable_mask = BIT(enbit), \ }, \ .qi = BIT(15), \ } #define MT6397_REG_FIXED(match, vreg, enreg, enbit, volt) \ [MT6397_ID_##vreg] = { \ .desc = { \ .name = #vreg, \ .of_match = of_match_ptr(match), \ .ops = &mt6397_volt_fixed_ops, \ .type = REGULATOR_VOLTAGE, \ .id = MT6397_ID_##vreg, \ .owner = THIS_MODULE, \ .n_voltages = 1, \ .enable_reg = enreg, \ .enable_mask = BIT(enbit), \ .min_uV = volt, \ }, \ .qi = BIT(15), \ } |
60ab7f415 regulator: use li... |
103 |
static const struct linear_range buck_volt_range1[] = { |
0425e2420 regulator: mt6397... |
104 105 |
REGULATOR_LINEAR_RANGE(700000, 0, 0x7f, 6250), }; |
60ab7f415 regulator: use li... |
106 |
static const struct linear_range buck_volt_range2[] = { |
0425e2420 regulator: mt6397... |
107 108 |
REGULATOR_LINEAR_RANGE(800000, 0, 0x7f, 6250), }; |
60ab7f415 regulator: use li... |
109 |
static const struct linear_range buck_volt_range3[] = { |
0425e2420 regulator: mt6397... |
110 111 |
REGULATOR_LINEAR_RANGE(1500000, 0, 0x1f, 20000), }; |
dc3b2881f regulator: mt6397... |
112 |
static const unsigned int ldo_volt_table1[] = { |
0425e2420 regulator: mt6397... |
113 114 |
1500000, 1800000, 2500000, 2800000, }; |
dc3b2881f regulator: mt6397... |
115 |
static const unsigned int ldo_volt_table2[] = { |
0425e2420 regulator: mt6397... |
116 117 |
1800000, 3300000, }; |
dc3b2881f regulator: mt6397... |
118 |
static const unsigned int ldo_volt_table3[] = { |
0425e2420 regulator: mt6397... |
119 120 |
3000000, 3300000, }; |
dc3b2881f regulator: mt6397... |
121 |
static const unsigned int ldo_volt_table4[] = { |
0425e2420 regulator: mt6397... |
122 123 |
1220000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000, }; |
dc3b2881f regulator: mt6397... |
124 |
static const unsigned int ldo_volt_table5[] = { |
0425e2420 regulator: mt6397... |
125 126 |
1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000, }; |
dc3b2881f regulator: mt6397... |
127 |
static const unsigned int ldo_volt_table5_v2[] = { |
0425e2420 regulator: mt6397... |
128 129 |
1200000, 1000000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000, }; |
dc3b2881f regulator: mt6397... |
130 |
static const unsigned int ldo_volt_table6[] = { |
0425e2420 regulator: mt6397... |
131 132 |
1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 2000000, }; |
dc3b2881f regulator: mt6397... |
133 |
static const unsigned int ldo_volt_table7[] = { |
0425e2420 regulator: mt6397... |
134 135 |
1300000, 1500000, 1800000, 2000000, 2500000, 2800000, 3000000, 3300000, }; |
8096236db regulator: mt6397... |
136 137 138 139 140 141 142 143 144 145 146 |
static unsigned int mt6397_map_mode(unsigned int mode) { switch (mode) { case MT6397_BUCK_MODE_AUTO: return REGULATOR_MODE_NORMAL; case MT6397_BUCK_MODE_FORCE_PWM: return REGULATOR_MODE_FAST; default: return REGULATOR_MODE_INVALID; } } |
056925132 regulator: mt6397... |
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
static int mt6397_regulator_set_mode(struct regulator_dev *rdev, unsigned int mode) { struct mt6397_regulator_info *info = rdev_get_drvdata(rdev); int ret, val; switch (mode) { case REGULATOR_MODE_FAST: val = MT6397_BUCK_MODE_FORCE_PWM; break; case REGULATOR_MODE_NORMAL: val = MT6397_BUCK_MODE_AUTO; break; default: ret = -EINVAL; goto err_mode; } dev_dbg(&rdev->dev, "mt6397 buck set_mode %#x, %#x, %#x, %#x ", info->modeset_reg, info->modeset_mask, info->modeset_shift, val); val <<= info->modeset_shift; ret = regmap_update_bits(rdev->regmap, info->modeset_reg, info->modeset_mask, val); err_mode: if (ret != 0) { dev_err(&rdev->dev, "Failed to set mt6397 buck mode: %d ", ret); return ret; } return 0; } static unsigned int mt6397_regulator_get_mode(struct regulator_dev *rdev) { struct mt6397_regulator_info *info = rdev_get_drvdata(rdev); int ret, regval; ret = regmap_read(rdev->regmap, info->modeset_reg, ®val); if (ret != 0) { dev_err(&rdev->dev, "Failed to get mt6397 buck mode: %d ", ret); return ret; } switch ((regval & info->modeset_mask) >> info->modeset_shift) { case MT6397_BUCK_MODE_AUTO: return REGULATOR_MODE_NORMAL; case MT6397_BUCK_MODE_FORCE_PWM: return REGULATOR_MODE_FAST; default: return -EINVAL; } } |
0425e2420 regulator: mt6397... |
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
static int mt6397_get_status(struct regulator_dev *rdev) { int ret; u32 regval; struct mt6397_regulator_info *info = rdev_get_drvdata(rdev); ret = regmap_read(rdev->regmap, info->desc.enable_reg, ®val); if (ret != 0) { dev_err(&rdev->dev, "Failed to get enable reg: %d ", ret); return ret; } return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF; } |
fb69114b3 regulator: mt6397... |
221 |
static const struct regulator_ops mt6397_volt_range_ops = { |
0425e2420 regulator: mt6397... |
222 223 224 225 226 227 228 229 230 |
.list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_time_sel = regulator_set_voltage_time_sel, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, .get_status = mt6397_get_status, |
056925132 regulator: mt6397... |
231 232 |
.set_mode = mt6397_regulator_set_mode, .get_mode = mt6397_regulator_get_mode, |
0425e2420 regulator: mt6397... |
233 |
}; |
fb69114b3 regulator: mt6397... |
234 |
static const struct regulator_ops mt6397_volt_table_ops = { |
0425e2420 regulator: mt6397... |
235 236 237 238 239 240 241 242 243 244 |
.list_voltage = regulator_list_voltage_table, .map_voltage = regulator_map_voltage_iterate, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_time_sel = regulator_set_voltage_time_sel, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, .get_status = mt6397_get_status, }; |
fb69114b3 regulator: mt6397... |
245 |
static const struct regulator_ops mt6397_volt_fixed_ops = { |
0425e2420 regulator: mt6397... |
246 247 248 249 250 251 252 253 254 255 256 |
.list_voltage = regulator_list_voltage_linear, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, .get_status = mt6397_get_status, }; /* The array is indexed by id(MT6397_ID_XXX) */ static struct mt6397_regulator_info mt6397_regulators[] = { MT6397_BUCK("buck_vpca15", VPCA15, 700000, 1493750, 6250, buck_volt_range1, MT6397_VCA15_CON7, MT6397_VCA15_CON9, 0x7f, |
056925132 regulator: mt6397... |
257 |
MT6397_VCA15_CON10, MT6397_VCA15_CON5, MT6397_VCA15_CON2, 11), |
0425e2420 regulator: mt6397... |
258 259 |
MT6397_BUCK("buck_vpca7", VPCA7, 700000, 1493750, 6250, buck_volt_range1, MT6397_VPCA7_CON7, MT6397_VPCA7_CON9, 0x7f, |
056925132 regulator: mt6397... |
260 |
MT6397_VPCA7_CON10, MT6397_VPCA7_CON5, MT6397_VPCA7_CON2, 8), |
0425e2420 regulator: mt6397... |
261 262 |
MT6397_BUCK("buck_vsramca15", VSRAMCA15, 700000, 1493750, 6250, buck_volt_range1, MT6397_VSRMCA15_CON7, MT6397_VSRMCA15_CON9, |
056925132 regulator: mt6397... |
263 264 |
0x7f, MT6397_VSRMCA15_CON10, MT6397_VSRMCA15_CON5, MT6397_VSRMCA15_CON2, 8), |
0425e2420 regulator: mt6397... |
265 266 |
MT6397_BUCK("buck_vsramca7", VSRAMCA7, 700000, 1493750, 6250, buck_volt_range1, MT6397_VSRMCA7_CON7, MT6397_VSRMCA7_CON9, |
056925132 regulator: mt6397... |
267 268 |
0x7f, MT6397_VSRMCA7_CON10, MT6397_VSRMCA7_CON5, MT6397_VSRMCA7_CON2, 8), |
0425e2420 regulator: mt6397... |
269 270 |
MT6397_BUCK("buck_vcore", VCORE, 700000, 1493750, 6250, buck_volt_range1, MT6397_VCORE_CON7, MT6397_VCORE_CON9, 0x7f, |
056925132 regulator: mt6397... |
271 |
MT6397_VCORE_CON10, MT6397_VCORE_CON5, MT6397_VCORE_CON2, 8), |
0425e2420 regulator: mt6397... |
272 273 |
MT6397_BUCK("buck_vgpu", VGPU, 700000, 1493750, 6250, buck_volt_range1, MT6397_VGPU_CON7, MT6397_VGPU_CON9, 0x7f, |
056925132 regulator: mt6397... |
274 |
MT6397_VGPU_CON10, MT6397_VGPU_CON5, MT6397_VGPU_CON2, 8), |
0425e2420 regulator: mt6397... |
275 276 |
MT6397_BUCK("buck_vdrm", VDRM, 800000, 1593750, 6250, buck_volt_range2, MT6397_VDRM_CON7, MT6397_VDRM_CON9, 0x7f, |
056925132 regulator: mt6397... |
277 |
MT6397_VDRM_CON10, MT6397_VDRM_CON5, MT6397_VDRM_CON2, 8), |
0425e2420 regulator: mt6397... |
278 279 |
MT6397_BUCK("buck_vio18", VIO18, 1500000, 2120000, 20000, buck_volt_range3, MT6397_VIO18_CON7, MT6397_VIO18_CON9, 0x1f, |
056925132 regulator: mt6397... |
280 |
MT6397_VIO18_CON10, MT6397_VIO18_CON5, MT6397_VIO18_CON2, 8), |
0425e2420 regulator: mt6397... |
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 |
MT6397_REG_FIXED("ldo_vtcxo", VTCXO, MT6397_ANALDO_CON0, 10, 2800000), MT6397_REG_FIXED("ldo_va28", VA28, MT6397_ANALDO_CON1, 14, 2800000), MT6397_LDO("ldo_vcama", VCAMA, ldo_volt_table1, MT6397_ANALDO_CON2, 15, MT6397_ANALDO_CON6, 0xC0), MT6397_REG_FIXED("ldo_vio28", VIO28, MT6397_DIGLDO_CON0, 14, 2800000), MT6397_REG_FIXED("ldo_vusb", VUSB, MT6397_DIGLDO_CON1, 14, 3300000), MT6397_LDO("ldo_vmc", VMC, ldo_volt_table2, MT6397_DIGLDO_CON2, 12, MT6397_DIGLDO_CON29, 0x10), MT6397_LDO("ldo_vmch", VMCH, ldo_volt_table3, MT6397_DIGLDO_CON3, 14, MT6397_DIGLDO_CON17, 0x80), MT6397_LDO("ldo_vemc3v3", VEMC3V3, ldo_volt_table3, MT6397_DIGLDO_CON4, 14, MT6397_DIGLDO_CON18, 0x10), MT6397_LDO("ldo_vgp1", VGP1, ldo_volt_table4, MT6397_DIGLDO_CON5, 15, MT6397_DIGLDO_CON19, 0xE0), MT6397_LDO("ldo_vgp2", VGP2, ldo_volt_table5, MT6397_DIGLDO_CON6, 15, MT6397_DIGLDO_CON20, 0xE0), MT6397_LDO("ldo_vgp3", VGP3, ldo_volt_table5, MT6397_DIGLDO_CON7, 15, MT6397_DIGLDO_CON21, 0xE0), MT6397_LDO("ldo_vgp4", VGP4, ldo_volt_table5, MT6397_DIGLDO_CON8, 15, MT6397_DIGLDO_CON22, 0xE0), MT6397_LDO("ldo_vgp5", VGP5, ldo_volt_table6, MT6397_DIGLDO_CON9, 15, MT6397_DIGLDO_CON23, 0xE0), MT6397_LDO("ldo_vgp6", VGP6, ldo_volt_table5, MT6397_DIGLDO_CON10, 15, MT6397_DIGLDO_CON33, 0xE0), MT6397_LDO("ldo_vibr", VIBR, ldo_volt_table7, MT6397_DIGLDO_CON24, 15, MT6397_DIGLDO_CON25, 0xE00), }; static int mt6397_set_buck_vosel_reg(struct platform_device *pdev) { struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent); int i; u32 regval; for (i = 0; i < MT6397_MAX_REGULATOR; i++) { if (mt6397_regulators[i].vselctrl_reg) { if (regmap_read(mt6397->regmap, mt6397_regulators[i].vselctrl_reg, ®val) < 0) { dev_err(&pdev->dev, "Failed to read buck ctrl "); return -EIO; } if (regval & mt6397_regulators[i].vselctrl_mask) { mt6397_regulators[i].desc.vsel_reg = mt6397_regulators[i].vselon_reg; } } } return 0; } static int mt6397_regulator_probe(struct platform_device *pdev) { struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent); struct regulator_config config = {}; struct regulator_dev *rdev; int i; u32 reg_value, version; /* Query buck controller to select activated voltage register part */ if (mt6397_set_buck_vosel_reg(pdev)) return -EIO; /* Read PMIC chip revision to update constraints and voltage table */ if (regmap_read(mt6397->regmap, MT6397_CID, ®_value) < 0) { dev_err(&pdev->dev, "Failed to read Chip ID "); return -EIO; } dev_info(&pdev->dev, "Chip ID = 0x%x ", reg_value); version = (reg_value & 0xFF); switch (version) { case MT6397_REGULATOR_ID91: mt6397_regulators[MT6397_ID_VGP2].desc.volt_table = ldo_volt_table5_v2; break; default: break; } for (i = 0; i < MT6397_MAX_REGULATOR; i++) { config.dev = &pdev->dev; config.driver_data = &mt6397_regulators[i]; config.regmap = mt6397->regmap; rdev = devm_regulator_register(&pdev->dev, &mt6397_regulators[i].desc, &config); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register %s ", mt6397_regulators[i].desc.name); return PTR_ERR(rdev); } } return 0; } |
288a89bf4 regulator: mt6397... |
383 384 385 386 387 |
static const struct platform_device_id mt6397_platform_ids[] = { {"mt6397-regulator", 0}, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(platform, mt6397_platform_ids); |
abbf043b6 regulator: mt6397... |
388 389 390 391 392 |
static const struct of_device_id mt6397_of_match[] = { { .compatible = "mediatek,mt6397-regulator", }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, mt6397_of_match); |
0425e2420 regulator: mt6397... |
393 394 395 |
static struct platform_driver mt6397_regulator_driver = { .driver = { .name = "mt6397-regulator", |
abbf043b6 regulator: mt6397... |
396 |
.of_match_table = of_match_ptr(mt6397_of_match), |
0425e2420 regulator: mt6397... |
397 398 |
}, .probe = mt6397_regulator_probe, |
288a89bf4 regulator: mt6397... |
399 |
.id_table = mt6397_platform_ids, |
0425e2420 regulator: mt6397... |
400 401 402 403 404 405 406 |
}; module_platform_driver(mt6397_regulator_driver); MODULE_AUTHOR("Flora Fu <flora.fu@mediatek.com>"); MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6397 PMIC"); MODULE_LICENSE("GPL"); |