1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // Copyright (c) 2022 Collabora Ltd. 4 // Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> 5 // 6 // Based on mt6323-regulator.c, 7 // Copyright (c) 2016 MediaTek Inc. 8 // 9 10 #include <linux/module.h> 11 #include <linux/of.h> 12 #include <linux/platform_device.h> 13 #include <linux/regmap.h> 14 #include <linux/mfd/mt6397/core.h> 15 #include <linux/mfd/mt6332/registers.h> 16 #include <linux/regulator/driver.h> 17 #include <linux/regulator/machine.h> 18 #include <linux/regulator/mt6332-regulator.h> 19 #include <linux/regulator/of_regulator.h> 20 21 #define MT6332_LDO_MODE_NORMAL 0 22 #define MT6332_LDO_MODE_LP 1 23 24 /* 25 * MT6332 regulators information 26 * 27 * @desc: standard fields of regulator description. 28 * @qi: Mask for query enable signal status of regulators 29 * @vselon_reg: Register sections for hardware control mode of bucks 30 * @vselctrl_reg: Register for controlling the buck control mode. 31 * @vselctrl_mask: Mask for query buck's voltage control mode. 32 * @status_reg: Register for regulator enable status where qi unavailable 33 * @status_mask: Mask for querying regulator enable status 34 */ 35 struct mt6332_regulator_info { 36 struct regulator_desc desc; 37 u32 qi; 38 u32 vselon_reg; 39 u32 vselctrl_reg; 40 u32 vselctrl_mask; 41 u32 modeset_reg; 42 u32 modeset_mask; 43 u32 status_reg; 44 u32 status_mask; 45 }; 46 47 #define MT6332_BUCK(match, vreg, min, max, step, volt_ranges, enreg, \ 48 vosel, vosel_mask, voselon, vosel_ctrl) \ 49 [MT6332_ID_##vreg] = { \ 50 .desc = { \ 51 .name = #vreg, \ 52 .of_match = of_match_ptr(match), \ 53 .ops = &mt6332_buck_volt_range_ops, \ 54 .type = REGULATOR_VOLTAGE, \ 55 .id = MT6332_ID_##vreg, \ 56 .owner = THIS_MODULE, \ 57 .n_voltages = (max - min)/step + 1, \ 58 .linear_ranges = volt_ranges, \ 59 .n_linear_ranges = ARRAY_SIZE(volt_ranges), \ 60 .vsel_reg = vosel, \ 61 .vsel_mask = vosel_mask, \ 62 .enable_reg = enreg, \ 63 .enable_mask = BIT(0), \ 64 }, \ 65 .qi = BIT(13), \ 66 .vselon_reg = voselon, \ 67 .vselctrl_reg = vosel_ctrl, \ 68 .vselctrl_mask = BIT(1), \ 69 .status_mask = 0, \ 70 } 71 72 #define MT6332_LDO_LINEAR(match, vreg, min, max, step, volt_ranges, \ 73 enreg, vosel, vosel_mask, voselon, \ 74 vosel_ctrl, _modeset_reg, _modeset_mask) \ 75 [MT6332_ID_##vreg] = { \ 76 .desc = { \ 77 .name = #vreg, \ 78 .of_match = of_match_ptr(match), \ 79 .ops = &mt6332_ldo_volt_range_ops, \ 80 .type = REGULATOR_VOLTAGE, \ 81 .id = MT6332_ID_##vreg, \ 82 .owner = THIS_MODULE, \ 83 .n_voltages = (max - min)/step + 1, \ 84 .linear_ranges = volt_ranges, \ 85 .n_linear_ranges = ARRAY_SIZE(volt_ranges), \ 86 .vsel_reg = vosel, \ 87 .vsel_mask = vosel_mask, \ 88 .enable_reg = enreg, \ 89 .enable_mask = BIT(0), \ 90 }, \ 91 .qi = BIT(15), \ 92 .vselon_reg = voselon, \ 93 .vselctrl_reg = vosel_ctrl, \ 94 .vselctrl_mask = BIT(1), \ 95 .modeset_reg = _modeset_reg, \ 96 .modeset_mask = _modeset_mask, \ 97 .status_mask = 0, \ 98 } 99 100 #define MT6332_LDO_AO(match, vreg, ldo_volt_table, vosel, vosel_mask) \ 101 [MT6332_ID_##vreg] = { \ 102 .desc = { \ 103 .name = #vreg, \ 104 .of_match = of_match_ptr(match), \ 105 .ops = &mt6332_volt_table_ao_ops, \ 106 .type = REGULATOR_VOLTAGE, \ 107 .id = MT6332_ID_##vreg, \ 108 .owner = THIS_MODULE, \ 109 .n_voltages = ARRAY_SIZE(ldo_volt_table), \ 110 .volt_table = ldo_volt_table, \ 111 .vsel_reg = vosel, \ 112 .vsel_mask = vosel_mask, \ 113 }, \ 114 } 115 116 #define MT6332_LDO(match, vreg, ldo_volt_table, enreg, enbit, vosel, \ 117 vosel_mask, _modeset_reg, _modeset_mask) \ 118 [MT6332_ID_##vreg] = { \ 119 .desc = { \ 120 .name = #vreg, \ 121 .of_match = of_match_ptr(match), \ 122 .ops = &mt6332_volt_table_ops, \ 123 .type = REGULATOR_VOLTAGE, \ 124 .id = MT6332_ID_##vreg, \ 125 .owner = THIS_MODULE, \ 126 .n_voltages = ARRAY_SIZE(ldo_volt_table), \ 127 .volt_table = ldo_volt_table, \ 128 .vsel_reg = vosel, \ 129 .vsel_mask = vosel_mask, \ 130 .enable_reg = enreg, \ 131 .enable_mask = BIT(enbit), \ 132 }, \ 133 .qi = BIT(15), \ 134 .modeset_reg = _modeset_reg, \ 135 .modeset_mask = _modeset_mask, \ 136 .status_mask = 0, \ 137 } 138 139 #define MT6332_REG_FIXED(match, vreg, enreg, enbit, qibit, volt, stbit) \ 140 [MT6332_ID_##vreg] = { \ 141 .desc = { \ 142 .name = #vreg, \ 143 .of_match = of_match_ptr(match), \ 144 .ops = &mt6332_volt_fixed_ops, \ 145 .type = REGULATOR_VOLTAGE, \ 146 .id = MT6332_ID_##vreg, \ 147 .owner = THIS_MODULE, \ 148 .n_voltages = 1, \ 149 .enable_reg = enreg, \ 150 .enable_mask = BIT(enbit), \ 151 .min_uV = volt, \ 152 }, \ 153 .qi = BIT(qibit), \ 154 .status_reg = MT6332_EN_STATUS0, \ 155 .status_mask = BIT(stbit), \ 156 } 157 158 static const struct linear_range boost_volt_range[] = { 159 REGULATOR_LINEAR_RANGE(3500000, 0, 0x7f, 31250), 160 }; 161 162 static const struct linear_range buck_volt_range[] = { 163 REGULATOR_LINEAR_RANGE(700000, 0, 0x7f, 6250), 164 }; 165 166 static const struct linear_range buck_pa_volt_range[] = { 167 REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000), 168 }; 169 170 static const struct linear_range buck_rf_volt_range[] = { 171 REGULATOR_LINEAR_RANGE(1050000, 0, 0x7f, 9375), 172 }; 173 174 static const unsigned int ldo_volt_table1[] = { 175 2800000, 3000000, 0, 3200000 176 }; 177 178 static const unsigned int ldo_volt_table2[] = { 179 1200000, 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1800000, 180 }; 181 182 static int mt6332_get_status(struct regulator_dev *rdev) 183 { 184 struct mt6332_regulator_info *info = rdev_get_drvdata(rdev); 185 u32 reg, en_mask, regval; 186 int ret; 187 188 if (info->qi > 0) { 189 reg = info->desc.enable_reg; 190 en_mask = info->qi; 191 } else { 192 reg = info->status_reg; 193 en_mask = info->status_mask; 194 } 195 196 ret = regmap_read(rdev->regmap, reg, ®val); 197 if (ret != 0) { 198 dev_err(&rdev->dev, "Failed to get enable reg: %d\n", ret); 199 return ret; 200 } 201 202 return (regval & en_mask) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF; 203 } 204 205 static int mt6332_ldo_set_mode(struct regulator_dev *rdev, unsigned int mode) 206 { 207 struct mt6332_regulator_info *info = rdev_get_drvdata(rdev); 208 int val; 209 210 switch (mode) { 211 case REGULATOR_MODE_STANDBY: 212 val = MT6332_LDO_MODE_LP; 213 break; 214 case REGULATOR_MODE_NORMAL: 215 val = MT6332_LDO_MODE_NORMAL; 216 break; 217 default: 218 return -EINVAL; 219 } 220 221 val <<= ffs(info->modeset_mask) - 1; 222 223 return regmap_update_bits(rdev->regmap, info->modeset_reg, 224 info->modeset_mask, val); 225 } 226 227 static unsigned int mt6332_ldo_get_mode(struct regulator_dev *rdev) 228 { 229 struct mt6332_regulator_info *info = rdev_get_drvdata(rdev); 230 unsigned int val; 231 int ret; 232 233 ret = regmap_read(rdev->regmap, info->modeset_reg, &val); 234 if (ret < 0) 235 return ret; 236 237 val &= info->modeset_mask; 238 val >>= ffs(info->modeset_mask) - 1; 239 240 return (val & BIT(0)) ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL; 241 } 242 243 static const struct regulator_ops mt6332_buck_volt_range_ops = { 244 .list_voltage = regulator_list_voltage_linear_range, 245 .map_voltage = regulator_map_voltage_linear_range, 246 .set_voltage_sel = regulator_set_voltage_sel_regmap, 247 .get_voltage_sel = regulator_get_voltage_sel_regmap, 248 .set_voltage_time_sel = regulator_set_voltage_time_sel, 249 .enable = regulator_enable_regmap, 250 .disable = regulator_disable_regmap, 251 .is_enabled = regulator_is_enabled_regmap, 252 .get_status = mt6332_get_status, 253 }; 254 255 static const struct regulator_ops mt6332_ldo_volt_range_ops = { 256 .list_voltage = regulator_list_voltage_linear_range, 257 .map_voltage = regulator_map_voltage_linear_range, 258 .set_voltage_sel = regulator_set_voltage_sel_regmap, 259 .get_voltage_sel = regulator_get_voltage_sel_regmap, 260 .set_voltage_time_sel = regulator_set_voltage_time_sel, 261 .enable = regulator_enable_regmap, 262 .disable = regulator_disable_regmap, 263 .is_enabled = regulator_is_enabled_regmap, 264 .get_status = mt6332_get_status, 265 .set_mode = mt6332_ldo_set_mode, 266 .get_mode = mt6332_ldo_get_mode, 267 }; 268 269 static const struct regulator_ops mt6332_volt_table_ops = { 270 .list_voltage = regulator_list_voltage_table, 271 .map_voltage = regulator_map_voltage_iterate, 272 .set_voltage_sel = regulator_set_voltage_sel_regmap, 273 .get_voltage_sel = regulator_get_voltage_sel_regmap, 274 .set_voltage_time_sel = regulator_set_voltage_time_sel, 275 .enable = regulator_enable_regmap, 276 .disable = regulator_disable_regmap, 277 .is_enabled = regulator_is_enabled_regmap, 278 .get_status = mt6332_get_status, 279 .set_mode = mt6332_ldo_set_mode, 280 .get_mode = mt6332_ldo_get_mode, 281 }; 282 283 static const struct regulator_ops mt6332_volt_table_ao_ops = { 284 .list_voltage = regulator_list_voltage_table, 285 .map_voltage = regulator_map_voltage_iterate, 286 .set_voltage_sel = regulator_set_voltage_sel_regmap, 287 .get_voltage_sel = regulator_get_voltage_sel_regmap, 288 .set_voltage_time_sel = regulator_set_voltage_time_sel, 289 }; 290 291 static const struct regulator_ops mt6332_volt_fixed_ops = { 292 .list_voltage = regulator_list_voltage_linear, 293 .enable = regulator_enable_regmap, 294 .disable = regulator_disable_regmap, 295 .is_enabled = regulator_is_enabled_regmap, 296 .get_status = mt6332_get_status, 297 }; 298 299 /* The array is indexed by id(MT6332_ID_XXX) */ 300 static struct mt6332_regulator_info mt6332_regulators[] = { 301 MT6332_BUCK("buck-vdram", VDRAM, 700000, 1493750, 6250, buck_volt_range, 302 MT6332_EN_STATUS0, MT6332_VDRAM_CON11, GENMASK(6, 0), 303 MT6332_VDRAM_CON12, MT6332_VDRAM_CON7), 304 MT6332_BUCK("buck-vdvfs2", VDVFS2, 700000, 1312500, 6250, buck_volt_range, 305 MT6332_VDVFS2_CON9, MT6332_VDVFS2_CON11, GENMASK(6, 0), 306 MT6332_VDVFS2_CON12, MT6332_VDVFS2_CON7), 307 MT6332_BUCK("buck-vpa", VPA, 500000, 3400000, 50000, buck_pa_volt_range, 308 MT6332_VPA_CON9, MT6332_VPA_CON11, GENMASK(5, 0), 309 MT6332_VPA_CON12, MT6332_VPA_CON7), 310 MT6332_BUCK("buck-vrf18a", VRF1, 1050000, 2240625, 9375, buck_rf_volt_range, 311 MT6332_VRF1_CON9, MT6332_VRF1_CON11, GENMASK(6, 0), 312 MT6332_VRF1_CON12, MT6332_VRF1_CON7), 313 MT6332_BUCK("buck-vrf18b", VRF2, 1050000, 2240625, 9375, buck_rf_volt_range, 314 MT6332_VRF2_CON9, MT6332_VRF2_CON11, GENMASK(6, 0), 315 MT6332_VRF2_CON12, MT6332_VRF2_CON7), 316 MT6332_BUCK("buck-vsbst", VSBST, 3500000, 7468750, 31250, boost_volt_range, 317 MT6332_VSBST_CON8, MT6332_VSBST_CON12, GENMASK(6, 0), 318 MT6332_VSBST_CON13, MT6332_VSBST_CON8), 319 MT6332_LDO("ldo-vauxb32", VAUXB32, ldo_volt_table1, MT6332_LDO_CON1, 10, 320 MT6332_LDO_CON9, GENMASK(6, 5), MT6332_LDO_CON1, GENMASK(1, 0)), 321 MT6332_REG_FIXED("ldo-vbif28", VBIF28, MT6332_LDO_CON2, 10, 0, 2800000, 1), 322 MT6332_REG_FIXED("ldo-vusb33", VUSB33, MT6332_LDO_CON3, 10, 0, 3300000, 2), 323 MT6332_LDO_LINEAR("ldo-vsram", VSRAM_DVFS2, 700000, 1493750, 6250, buck_volt_range, 324 MT6332_EN_STATUS0, MT6332_LDO_CON8, GENMASK(15, 9), 325 MT6332_VDVFS2_CON23, MT6332_VDVFS2_CON22, 326 MT6332_LDO_CON5, GENMASK(1, 0)), 327 MT6332_LDO_AO("ldo-vdig18", VDIG18, ldo_volt_table2, MT6332_LDO_CON12, GENMASK(11, 9)), 328 }; 329 330 static int mt6332_set_buck_vosel_reg(struct platform_device *pdev) 331 { 332 struct mt6397_chip *mt6332 = dev_get_drvdata(pdev->dev.parent); 333 int i; 334 u32 regval; 335 336 for (i = 0; i < MT6332_ID_VREG_MAX; i++) { 337 if (mt6332_regulators[i].vselctrl_reg) { 338 if (regmap_read(mt6332->regmap, 339 mt6332_regulators[i].vselctrl_reg, 340 ®val) < 0) { 341 dev_err(&pdev->dev, 342 "Failed to read buck ctrl\n"); 343 return -EIO; 344 } 345 346 if (regval & mt6332_regulators[i].vselctrl_mask) { 347 mt6332_regulators[i].desc.vsel_reg = 348 mt6332_regulators[i].vselon_reg; 349 } 350 } 351 } 352 353 return 0; 354 } 355 356 static int mt6332_regulator_probe(struct platform_device *pdev) 357 { 358 struct mt6397_chip *mt6332 = dev_get_drvdata(pdev->dev.parent); 359 struct regulator_config config = {}; 360 struct regulator_dev *rdev; 361 int i; 362 u32 reg_value; 363 364 /* Query buck controller to select activated voltage register part */ 365 if (mt6332_set_buck_vosel_reg(pdev)) 366 return -EIO; 367 368 /* Read PMIC chip revision to update constraints and voltage table */ 369 if (regmap_read(mt6332->regmap, MT6332_HWCID, ®_value) < 0) { 370 dev_err(&pdev->dev, "Failed to read Chip ID\n"); 371 return -EIO; 372 } 373 reg_value &= GENMASK(7, 0); 374 375 dev_info(&pdev->dev, "Chip ID = 0x%x\n", reg_value); 376 377 /* 378 * ChipID 0x10 is "MT6332 E1", has a different voltage table and 379 * it's currently not supported in this driver. Upon detection of 380 * this ID, refuse to register the regulators, as we will wrongly 381 * interpret the VSEL for this revision, potentially overvolting 382 * some device. 383 */ 384 if (reg_value == 0x10) { 385 dev_err(&pdev->dev, "Chip version not supported. Bailing out.\n"); 386 return -EINVAL; 387 } 388 389 for (i = 0; i < MT6332_ID_VREG_MAX; i++) { 390 config.dev = &pdev->dev; 391 config.driver_data = &mt6332_regulators[i]; 392 config.regmap = mt6332->regmap; 393 rdev = devm_regulator_register(&pdev->dev, 394 &mt6332_regulators[i].desc, &config); 395 if (IS_ERR(rdev)) { 396 dev_err(&pdev->dev, "failed to register %s\n", 397 mt6332_regulators[i].desc.name); 398 return PTR_ERR(rdev); 399 } 400 } 401 return 0; 402 } 403 404 static const struct platform_device_id mt6332_platform_ids[] = { 405 {"mt6332-regulator", 0}, 406 { /* sentinel */ }, 407 }; 408 MODULE_DEVICE_TABLE(platform, mt6332_platform_ids); 409 410 static struct platform_driver mt6332_regulator_driver = { 411 .driver = { 412 .name = "mt6332-regulator", 413 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 414 }, 415 .probe = mt6332_regulator_probe, 416 .id_table = mt6332_platform_ids, 417 }; 418 419 module_platform_driver(mt6332_regulator_driver); 420 421 MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>"); 422 MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6332 PMIC"); 423 MODULE_LICENSE("GPL"); 424