Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

regulator: add mt6357 regulator

Add regulator driver for the MT6357 PMIC.

Signed-off-by: Fabien Parent <fparent@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Alexandre Mergnat <amergnat@baylibre.com>
Link: https://lore.kernel.org/r/20221005-mt6357-support-v7-7-477e60126749@baylibre.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Fabien Parent and committed by
Mark Brown
dafc7cde b4387db1

+514
+9
drivers/regulator/Kconfig
··· 805 805 This driver supports the control of different power rails of device 806 806 through regulator interface 807 807 808 + config REGULATOR_MT6357 809 + tristate "MediaTek MT6357 PMIC" 810 + depends on MFD_MT6397 811 + help 812 + Say y here to select this option to enable the power regulator of 813 + MediaTek MT6357 PMIC. 814 + This driver supports the control of different power rails of device 815 + through regulator interface. 816 + 808 817 config REGULATOR_MT6358 809 818 tristate "MediaTek MT6358 PMIC" 810 819 depends on MFD_MT6397
+1
drivers/regulator/Makefile
··· 97 97 obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o 98 98 obj-$(CONFIG_REGULATOR_MT6331) += mt6331-regulator.o 99 99 obj-$(CONFIG_REGULATOR_MT6332) += mt6332-regulator.o 100 + obj-$(CONFIG_REGULATOR_MT6357) += mt6357-regulator.o 100 101 obj-$(CONFIG_REGULATOR_MT6358) += mt6358-regulator.o 101 102 obj-$(CONFIG_REGULATOR_MT6359) += mt6359-regulator.o 102 103 obj-$(CONFIG_REGULATOR_MT6360) += mt6360-regulator.o
+453
drivers/regulator/mt6357-regulator.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // Copyright (c) 2022 MediaTek Inc. 4 + // Copyright (c) 2022 BayLibre, SAS. 5 + // Author: Chen Zhong <chen.zhong@mediatek.com> 6 + // Author: Fabien Parent <fparent@baylibre.com> 7 + // Author: Alexandre Mergnat <amergnat@baylibre.com> 8 + // 9 + // Based on mt6397-regulator.c 10 + // 11 + 12 + #include <linux/module.h> 13 + #include <linux/of.h> 14 + #include <linux/platform_device.h> 15 + #include <linux/regmap.h> 16 + #include <linux/mfd/mt6397/core.h> 17 + #include <linux/mfd/mt6357/registers.h> 18 + #include <linux/regulator/driver.h> 19 + #include <linux/regulator/machine.h> 20 + #include <linux/regulator/mt6357-regulator.h> 21 + #include <linux/regulator/of_regulator.h> 22 + 23 + /* 24 + * MT6357 regulators' information 25 + * 26 + * @desc: standard fields of regulator description. 27 + * @da_vsel_reg: Monitor register for query buck's voltage. 28 + * @da_vsel_mask: Mask for query buck's voltage. 29 + */ 30 + struct mt6357_regulator_info { 31 + struct regulator_desc desc; 32 + u32 da_vsel_reg; 33 + u32 da_vsel_mask; 34 + }; 35 + 36 + #define MT6357_BUCK(match, vreg, min, max, step, \ 37 + volt_ranges, vosel_reg, vosel_mask, _da_vsel_mask) \ 38 + [MT6357_ID_##vreg] = { \ 39 + .desc = { \ 40 + .name = #vreg, \ 41 + .of_match = of_match_ptr(match), \ 42 + .regulators_node = "regulators", \ 43 + .ops = &mt6357_volt_range_ops, \ 44 + .type = REGULATOR_VOLTAGE, \ 45 + .id = MT6357_ID_##vreg, \ 46 + .owner = THIS_MODULE, \ 47 + .n_voltages = ((max) - (min)) / (step) + 1, \ 48 + .linear_ranges = volt_ranges, \ 49 + .n_linear_ranges = ARRAY_SIZE(volt_ranges), \ 50 + .vsel_reg = vosel_reg, \ 51 + .vsel_mask = vosel_mask, \ 52 + .enable_reg = MT6357_BUCK_##vreg##_CON0, \ 53 + .enable_mask = BIT(0), \ 54 + }, \ 55 + .da_vsel_reg = MT6357_BUCK_##vreg##_DBG0, \ 56 + .da_vsel_mask = vosel_mask, \ 57 + } 58 + 59 + #define MT6357_LDO(match, vreg, ldo_volt_table, \ 60 + enreg, vosel, vosel_mask) \ 61 + [MT6357_ID_##vreg] = { \ 62 + .desc = { \ 63 + .name = #vreg, \ 64 + .of_match = of_match_ptr(match), \ 65 + .regulators_node = "regulators", \ 66 + .ops = &mt6357_volt_table_ops, \ 67 + .type = REGULATOR_VOLTAGE, \ 68 + .id = MT6357_ID_##vreg, \ 69 + .owner = THIS_MODULE, \ 70 + .n_voltages = ARRAY_SIZE(ldo_volt_table), \ 71 + .volt_table = ldo_volt_table, \ 72 + .vsel_reg = vosel, \ 73 + .vsel_mask = vosel_mask, \ 74 + .enable_reg = enreg, \ 75 + .enable_mask = BIT(0), \ 76 + }, \ 77 + } 78 + 79 + #define MT6357_LDO1(match, vreg, min, max, step, volt_ranges, \ 80 + enreg, vosel, vosel_mask) \ 81 + [MT6357_ID_##vreg] = { \ 82 + .desc = { \ 83 + .name = #vreg, \ 84 + .of_match = of_match_ptr(match), \ 85 + .regulators_node = "regulators", \ 86 + .ops = &mt6357_volt_range_ops, \ 87 + .type = REGULATOR_VOLTAGE, \ 88 + .id = MT6357_ID_##vreg, \ 89 + .owner = THIS_MODULE, \ 90 + .n_voltages = ((max) - (min)) / (step) + 1, \ 91 + .linear_ranges = volt_ranges, \ 92 + .n_linear_ranges = ARRAY_SIZE(volt_ranges), \ 93 + .vsel_reg = vosel, \ 94 + .vsel_mask = vosel_mask, \ 95 + .enable_reg = enreg, \ 96 + .enable_mask = BIT(0), \ 97 + }, \ 98 + .da_vsel_reg = MT6357_LDO_##vreg##_DBG0, \ 99 + .da_vsel_mask = 0x7f00, \ 100 + } 101 + 102 + #define MT6357_REG_FIXED(match, vreg, volt) \ 103 + [MT6357_ID_##vreg] = { \ 104 + .desc = { \ 105 + .name = #vreg, \ 106 + .of_match = of_match_ptr(match), \ 107 + .regulators_node = "regulators", \ 108 + .ops = &mt6357_volt_fixed_ops, \ 109 + .type = REGULATOR_VOLTAGE, \ 110 + .id = MT6357_ID_##vreg, \ 111 + .owner = THIS_MODULE, \ 112 + .n_voltages = 1, \ 113 + .enable_reg = MT6357_LDO_##vreg##_CON0, \ 114 + .enable_mask = BIT(0), \ 115 + .min_uV = volt, \ 116 + }, \ 117 + } 118 + 119 + /** 120 + * mt6357_get_buck_voltage_sel - get_voltage_sel for regmap users 121 + * 122 + * @rdev: regulator to operate on 123 + * 124 + * Regulators that use regmap for their register I/O can set the 125 + * da_vsel_reg and da_vsel_mask fields in the info structure and 126 + * then use this as their get_voltage_vsel operation. 127 + */ 128 + static int mt6357_get_buck_voltage_sel(struct regulator_dev *rdev) 129 + { 130 + int ret, regval; 131 + struct mt6357_regulator_info *info = rdev_get_drvdata(rdev); 132 + 133 + ret = regmap_read(rdev->regmap, info->da_vsel_reg, &regval); 134 + if (ret != 0) { 135 + dev_err(&rdev->dev, 136 + "Failed to get mt6357 Buck %s vsel reg: %d\n", 137 + info->desc.name, ret); 138 + return ret; 139 + } 140 + 141 + regval &= info->da_vsel_mask; 142 + regval >>= ffs(info->da_vsel_mask) - 1; 143 + 144 + return regval; 145 + } 146 + 147 + static const struct regulator_ops mt6357_volt_range_ops = { 148 + .list_voltage = regulator_list_voltage_linear_range, 149 + .map_voltage = regulator_map_voltage_linear_range, 150 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 151 + .get_voltage_sel = mt6357_get_buck_voltage_sel, 152 + .set_voltage_time_sel = regulator_set_voltage_time_sel, 153 + .enable = regulator_enable_regmap, 154 + .disable = regulator_disable_regmap, 155 + .is_enabled = regulator_is_enabled_regmap, 156 + }; 157 + 158 + static const struct regulator_ops mt6357_volt_table_ops = { 159 + .list_voltage = regulator_list_voltage_table, 160 + .map_voltage = regulator_map_voltage_iterate, 161 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 162 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 163 + .set_voltage_time_sel = regulator_set_voltage_time_sel, 164 + .enable = regulator_enable_regmap, 165 + .disable = regulator_disable_regmap, 166 + .is_enabled = regulator_is_enabled_regmap, 167 + }; 168 + 169 + static const struct regulator_ops mt6357_volt_fixed_ops = { 170 + .list_voltage = regulator_list_voltage_linear, 171 + .enable = regulator_enable_regmap, 172 + .disable = regulator_disable_regmap, 173 + .is_enabled = regulator_is_enabled_regmap, 174 + }; 175 + 176 + static const int vxo22_voltages[] = { 177 + 2200000, 178 + 0, 179 + 2400000, 180 + }; 181 + 182 + static const int vefuse_voltages[] = { 183 + 1200000, 184 + 1300000, 185 + 1500000, 186 + 0, 187 + 1800000, 188 + 0, 189 + 0, 190 + 0, 191 + 0, 192 + 2800000, 193 + 2900000, 194 + 3000000, 195 + 0, 196 + 3300000, 197 + }; 198 + 199 + static const int vcn33_voltages[] = { 200 + 0, 201 + 3300000, 202 + 3400000, 203 + 3500000, 204 + }; 205 + 206 + static const int vcama_voltages[] = { 207 + 0, 208 + 0, 209 + 0, 210 + 0, 211 + 0, 212 + 0, 213 + 0, 214 + 2500000, 215 + 0, 216 + 0, 217 + 2800000, 218 + }; 219 + 220 + static const int vcamd_voltages[] = { 221 + 0, 222 + 0, 223 + 0, 224 + 0, 225 + 1000000, 226 + 1100000, 227 + 1200000, 228 + 1300000, 229 + 0, 230 + 1500000, 231 + 0, 232 + 0, 233 + 1800000, 234 + }; 235 + 236 + static const int vldo28_voltages[] = { 237 + 0, 238 + 2800000, 239 + 0, 240 + 3000000, 241 + }; 242 + 243 + static const int vdram_voltages[] = { 244 + 0, 245 + 1100000, 246 + 1200000, 247 + }; 248 + 249 + static const int vsim_voltages[] = { 250 + 0, 251 + 0, 252 + 0, 253 + 1700000, 254 + 1800000, 255 + 0, 256 + 0, 257 + 0, 258 + 2700000, 259 + 0, 260 + 0, 261 + 3000000, 262 + 3100000, 263 + }; 264 + 265 + static const int vibr_voltages[] = { 266 + 1200000, 267 + 1300000, 268 + 1500000, 269 + 0, 270 + 1800000, 271 + 2000000, 272 + 0, 273 + 0, 274 + 0, 275 + 2800000, 276 + 0, 277 + 3000000, 278 + 0, 279 + 3300000, 280 + }; 281 + 282 + static const int vmc_voltages[] = { 283 + 0, 284 + 0, 285 + 0, 286 + 0, 287 + 1800000, 288 + 0, 289 + 0, 290 + 0, 291 + 0, 292 + 0, 293 + 2900000, 294 + 3000000, 295 + 0, 296 + 3300000, 297 + }; 298 + 299 + static const int vmch_voltages[] = { 300 + 0, 301 + 0, 302 + 2900000, 303 + 3000000, 304 + 0, 305 + 3300000, 306 + }; 307 + 308 + static const int vemc_voltages[] = { 309 + 0, 310 + 0, 311 + 2900000, 312 + 3000000, 313 + 0, 314 + 3300000, 315 + }; 316 + 317 + static const int vusb_voltages[] = { 318 + 0, 319 + 0, 320 + 0, 321 + 3000000, 322 + 3100000, 323 + }; 324 + 325 + static const struct linear_range buck_volt_range1[] = { 326 + REGULATOR_LINEAR_RANGE(518750, 0, 0x7f, 6250), 327 + }; 328 + 329 + static const struct linear_range buck_volt_range2[] = { 330 + REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 6250), 331 + }; 332 + 333 + static const struct linear_range buck_volt_range3[] = { 334 + REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000), 335 + }; 336 + 337 + static const struct linear_range buck_volt_range4[] = { 338 + REGULATOR_LINEAR_RANGE(1200000, 0, 0x7f, 12500), 339 + }; 340 + 341 + /* The array is indexed by id(MT6357_ID_XXX) */ 342 + static struct mt6357_regulator_info mt6357_regulators[] = { 343 + /* Bucks */ 344 + MT6357_BUCK("buck-vcore", VCORE, 518750, 1312500, 6250, 345 + buck_volt_range1, MT6357_BUCK_VCORE_ELR0, 0x7f, 0x7f), 346 + MT6357_BUCK("buck-vproc", VPROC, 518750, 1312500, 6250, 347 + buck_volt_range1, MT6357_BUCK_VPROC_ELR0, 0x7f, 0x7f), 348 + MT6357_BUCK("buck-vmodem", VMODEM, 500000, 1293750, 6250, 349 + buck_volt_range2, MT6357_BUCK_VMODEM_ELR0, 0x7f, 0x7f), 350 + MT6357_BUCK("buck-vpa", VPA, 500000, 3650000, 50000, 351 + buck_volt_range3, MT6357_BUCK_VPA_CON1, 0x3f, 0x3f), 352 + MT6357_BUCK("buck-vs1", VS1, 1200000, 2787500, 12500, 353 + buck_volt_range4, MT6357_BUCK_VS1_ELR0, 0x7f, 0x7f), 354 + 355 + /* LDOs */ 356 + MT6357_LDO("ldo-vcama", VCAMA, vcama_voltages, 357 + MT6357_LDO_VCAMA_CON0, MT6357_VCAMA_ANA_CON0, 0xf00), 358 + MT6357_LDO("ldo-vcamd", VCAMD, vcamd_voltages, 359 + MT6357_LDO_VCAMD_CON0, MT6357_VCAMD_ANA_CON0, 0xf00), 360 + MT6357_LDO("ldo-vcn33-bt", VCN33_BT, vcn33_voltages, 361 + MT6357_LDO_VCN33_CON0_0, MT6357_VCN33_ANA_CON0, 0x300), 362 + MT6357_LDO("ldo-vcn33-wifi", VCN33_WIFI, vcn33_voltages, 363 + MT6357_LDO_VCN33_CON0_1, MT6357_VCN33_ANA_CON0, 0x300), 364 + MT6357_LDO("ldo-vdram", VDRAM, vdram_voltages, 365 + MT6357_LDO_VDRAM_CON0, MT6357_VDRAM_ELR_2, 0x300), 366 + MT6357_LDO("ldo-vefuse", VEFUSE, vefuse_voltages, 367 + MT6357_LDO_VEFUSE_CON0, MT6357_VEFUSE_ANA_CON0, 0xf00), 368 + MT6357_LDO("ldo-vemc", VEMC, vemc_voltages, 369 + MT6357_LDO_VEMC_CON0, MT6357_VEMC_ANA_CON0, 0x700), 370 + MT6357_LDO("ldo-vibr", VIBR, vibr_voltages, 371 + MT6357_LDO_VIBR_CON0, MT6357_VIBR_ANA_CON0, 0xf00), 372 + MT6357_LDO("ldo-vldo28", VLDO28, vldo28_voltages, 373 + MT6357_LDO_VLDO28_CON0_0, MT6357_VLDO28_ANA_CON0, 0x300), 374 + MT6357_LDO("ldo-vmc", VMC, vmc_voltages, 375 + MT6357_LDO_VMC_CON0, MT6357_VMC_ANA_CON0, 0xf00), 376 + MT6357_LDO("ldo-vmch", VMCH, vmch_voltages, 377 + MT6357_LDO_VMCH_CON0, MT6357_VMCH_ANA_CON0, 0x700), 378 + MT6357_LDO("ldo-vsim1", VSIM1, vsim_voltages, 379 + MT6357_LDO_VSIM1_CON0, MT6357_VSIM1_ANA_CON0, 0xf00), 380 + MT6357_LDO("ldo-vsim2", VSIM2, vsim_voltages, 381 + MT6357_LDO_VSIM2_CON0, MT6357_VSIM2_ANA_CON0, 0xf00), 382 + MT6357_LDO("ldo-vusb33", VUSB33, vusb_voltages, 383 + MT6357_LDO_VUSB33_CON0_0, MT6357_VUSB33_ANA_CON0, 0x700), 384 + MT6357_LDO("ldo-vxo22", VXO22, vxo22_voltages, 385 + MT6357_LDO_VXO22_CON0, MT6357_VXO22_ANA_CON0, 0x300), 386 + 387 + MT6357_LDO1("ldo-vsram-proc", VSRAM_PROC, 518750, 1312500, 6250, 388 + buck_volt_range1, MT6357_LDO_VSRAM_PROC_CON0, 389 + MT6357_LDO_VSRAM_CON0, 0x7f00), 390 + MT6357_LDO1("ldo-vsram-others", VSRAM_OTHERS, 518750, 1312500, 6250, 391 + buck_volt_range1, MT6357_LDO_VSRAM_OTHERS_CON0, 392 + MT6357_LDO_VSRAM_CON1, 0x7f00), 393 + 394 + MT6357_REG_FIXED("ldo-vaud28", VAUD28, 2800000), 395 + MT6357_REG_FIXED("ldo-vaux18", VAUX18, 1800000), 396 + MT6357_REG_FIXED("ldo-vcamio18", VCAMIO, 1800000), 397 + MT6357_REG_FIXED("ldo-vcn18", VCN18, 1800000), 398 + MT6357_REG_FIXED("ldo-vcn28", VCN28, 2800000), 399 + MT6357_REG_FIXED("ldo-vfe28", VFE28, 2800000), 400 + MT6357_REG_FIXED("ldo-vio18", VIO18, 1800000), 401 + MT6357_REG_FIXED("ldo-vio28", VIO28, 2800000), 402 + MT6357_REG_FIXED("ldo-vrf12", VRF12, 1200000), 403 + MT6357_REG_FIXED("ldo-vrf18", VRF18, 1800000), 404 + }; 405 + 406 + static int mt6357_regulator_probe(struct platform_device *pdev) 407 + { 408 + struct mt6397_chip *mt6357 = dev_get_drvdata(pdev->dev.parent); 409 + struct regulator_config config = {}; 410 + struct regulator_dev *rdev; 411 + int i; 412 + 413 + pdev->dev.of_node = pdev->dev.parent->of_node; 414 + 415 + for (i = 0; i < MT6357_MAX_REGULATOR; i++) { 416 + config.dev = &pdev->dev; 417 + config.driver_data = &mt6357_regulators[i]; 418 + config.regmap = mt6357->regmap; 419 + 420 + rdev = devm_regulator_register(&pdev->dev, 421 + &mt6357_regulators[i].desc, 422 + &config); 423 + if (IS_ERR(rdev)) { 424 + dev_err(&pdev->dev, "failed to register %s\n", 425 + mt6357_regulators[i].desc.name); 426 + return PTR_ERR(rdev); 427 + } 428 + } 429 + 430 + return 0; 431 + } 432 + 433 + static const struct platform_device_id mt6357_platform_ids[] = { 434 + { "mt6357-regulator" }, 435 + { /* sentinel */ }, 436 + }; 437 + MODULE_DEVICE_TABLE(platform, mt6357_platform_ids); 438 + 439 + static struct platform_driver mt6357_regulator_driver = { 440 + .driver = { 441 + .name = "mt6357-regulator", 442 + }, 443 + .probe = mt6357_regulator_probe, 444 + .id_table = mt6357_platform_ids, 445 + }; 446 + 447 + module_platform_driver(mt6357_regulator_driver); 448 + 449 + MODULE_AUTHOR("Chen Zhong <chen.zhong@mediatek.com>"); 450 + MODULE_AUTHOR("Fabien Parent <fabien.parent@linaro.org>"); 451 + MODULE_AUTHOR("Alexandre Mergnat <amergnat@baylibre.com>"); 452 + MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6357 PMIC"); 453 + MODULE_LICENSE("GPL");
+51
include/linux/regulator/mt6357-regulator.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2022 MediaTek Inc. 4 + */ 5 + 6 + #ifndef __LINUX_REGULATOR_MT6357_H 7 + #define __LINUX_REGULATOR_MT6357_H 8 + 9 + enum { 10 + /* Bucks */ 11 + MT6357_ID_VCORE, 12 + MT6357_ID_VMODEM, 13 + MT6357_ID_VPA, 14 + MT6357_ID_VPROC, 15 + MT6357_ID_VS1, 16 + 17 + /* LDOs */ 18 + MT6357_ID_VAUX18, 19 + MT6357_ID_VAUD28, 20 + MT6357_ID_VCAMA, 21 + MT6357_ID_VCAMD, 22 + MT6357_ID_VCAMIO, 23 + MT6357_ID_VCN18, 24 + MT6357_ID_VCN28, 25 + MT6357_ID_VCN33_BT, 26 + MT6357_ID_VCN33_WIFI, 27 + MT6357_ID_VDRAM, 28 + MT6357_ID_VEFUSE, 29 + MT6357_ID_VEMC, 30 + MT6357_ID_VFE28, 31 + MT6357_ID_VIBR, 32 + MT6357_ID_VIO18, 33 + MT6357_ID_VIO28, 34 + MT6357_ID_VLDO28, 35 + MT6357_ID_VMC, 36 + MT6357_ID_VMCH, 37 + MT6357_ID_VRF12, 38 + MT6357_ID_VRF18, 39 + MT6357_ID_VSIM1, 40 + MT6357_ID_VSIM2, 41 + MT6357_ID_VSRAM_OTHERS, 42 + MT6357_ID_VSRAM_PROC, 43 + MT6357_ID_VUSB33, 44 + MT6357_ID_VXO22, 45 + 46 + MT6357_ID_RG_MAX, 47 + }; 48 + 49 + #define MT6357_MAX_REGULATOR MT6357_ID_RG_MAX 50 + 51 + #endif /* __LINUX_REGULATOR_MT6357_H */