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

Add support MT6316/6363/MT6373 PMICs regulators

Merge series from AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>:

This series adds support for three new MediaTek PMICs: MT6316, MT6363
and MT6373 and their variants - used in board designs featuring the
MediaTek MT8196 Chromebook SoC, or the MT6991 Dimensity 9400 Smartphone
SoC.

In particular, MT6316 is a regulator, but the MT6363 and MT6373 PMICs
are multi-function devices, as they have and expose multiple sub-devices;
moreover, some of those also contain an interrupt controller, managing
internal IPs interrupts: for those, a chained interrupt handler is
registered, which parent is the SPMI controller itself.

This series adds support for all of the MT6316 regulator variants and
for MT6363, MT6373 SPMI PMICs and their interrupt controller.

+2008
+76
Documentation/devicetree/bindings/regulator/mediatek,mt6316b-regulator.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/regulator/mediatek,mt6316b-regulator.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: MediaTek MT6316 BP/VP SPMI PMIC Regulators 8 + 9 + maintainers: 10 + - AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> 11 + 12 + description: 13 + The MediaTek MT6316BP/VP PMICs are fully controlled by SPMI interface, both 14 + feature four step-down DC/DC (buck) converters, and provides 2+2 Phases, 15 + joining Buck 1+2 for the first phase, and Buck 3+4 for the second phase. 16 + 17 + properties: 18 + compatible: 19 + const: mediatek,mt6316b-regulator 20 + 21 + reg: 22 + maxItems: 1 23 + 24 + patternProperties: 25 + "^vbuck(12|34)$": 26 + type: object 27 + $ref: regulator.yaml# 28 + unevaluatedProperties: false 29 + properties: 30 + regulator-allowed-modes: 31 + description: | 32 + Allowed Buck regulator operating modes allowed. Valid values below. 33 + 0 - Normal mode with automatic power saving, reducing the switching 34 + frequency when light load conditions are detected 35 + 1 - Forced Continuous Conduction mode (FCCM) for improved voltage 36 + regulation accuracy with constant switching frequency but lower 37 + regulator efficiency 38 + 2 - Forced Low Power mode for improved regulator efficiency, used 39 + when no heavy load is expected, will shut down unnecessary IP 40 + blocks and secondary phases to reduce quiescent current. 41 + This mode does not limit the maximum output current but unless 42 + only a light load is applied, there will be regulation accuracy 43 + and efficiency losses. 44 + minItems: 1 45 + maxItems: 3 46 + items: 47 + enum: [ 0, 1, 2 ] 48 + 49 + required: 50 + - compatible 51 + - reg 52 + 53 + additionalProperties: false 54 + 55 + examples: 56 + - | 57 + #include <dt-bindings/spmi/spmi.h> 58 + 59 + spmi { 60 + #address-cells = <2>; 61 + #size-cells = <0>; 62 + 63 + pmic@8 { 64 + compatible = "mediatek,mt6316b-regulator"; 65 + reg = <0x8 SPMI_USID>; 66 + 67 + vbuck12 { 68 + regulator-name = "dvdd_core"; 69 + regulator-min-microvolt = <450000>; 70 + regulator-max-microvolt = <965000>; 71 + regulator-allowed-modes = <0 1 2>; 72 + regulator-enable-ramp-delay = <256>; 73 + }; 74 + }; 75 + }; 76 + ...
+76
Documentation/devicetree/bindings/regulator/mediatek,mt6316c-regulator.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/regulator/mediatek,mt6316c-regulator.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: MediaTek MT6316 CP/HP/KP SPMI PMIC Regulators 8 + 9 + maintainers: 10 + - AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> 11 + 12 + description: 13 + The MediaTek MT6316CP/HP/KP PMICs are fully controlled by SPMI interface, 14 + features four step-down DC/DC (buck) converters, and provides 3+1 Phases, 15 + joining Buck 1+2+4 for the first phase, and uses Buck 3 for the second. 16 + 17 + properties: 18 + compatible: 19 + const: mediatek,mt6316c-regulator 20 + 21 + reg: 22 + maxItems: 1 23 + 24 + patternProperties: 25 + "^vbuck(124|3)$": 26 + type: object 27 + $ref: regulator.yaml# 28 + unevaluatedProperties: false 29 + properties: 30 + regulator-allowed-modes: 31 + description: | 32 + Allowed Buck regulator operating modes allowed. Valid values below. 33 + 0 - Normal mode with automatic power saving, reducing the switching 34 + frequency when light load conditions are detected 35 + 1 - Forced Continuous Conduction mode (FCCM) for improved voltage 36 + regulation accuracy with constant switching frequency but lower 37 + regulator efficiency 38 + 2 - Forced Low Power mode for improved regulator efficiency, used 39 + when no heavy load is expected, will shut down unnecessary IP 40 + blocks and secondary phases to reduce quiescent current. 41 + This mode does not limit the maximum output current but unless 42 + only a light load is applied, there will be regulation accuracy 43 + and efficiency losses. 44 + minItems: 1 45 + maxItems: 3 46 + items: 47 + enum: [ 0, 1, 2 ] 48 + 49 + required: 50 + - compatible 51 + - reg 52 + 53 + additionalProperties: false 54 + 55 + examples: 56 + - | 57 + #include <dt-bindings/spmi/spmi.h> 58 + 59 + spmi { 60 + #address-cells = <2>; 61 + #size-cells = <0>; 62 + 63 + pmic@6 { 64 + compatible = "mediatek,mt6316c-regulator"; 65 + reg = <0x6 SPMI_USID>; 66 + 67 + vbuck124 { 68 + regulator-name = "dvdd_proc_m"; 69 + regulator-min-microvolt = <450000>; 70 + regulator-max-microvolt = <1277500>; 71 + regulator-allowed-modes = <0 1 2>; 72 + regulator-enable-ramp-delay = <256>; 73 + }; 74 + }; 75 + }; 76 + ...
+75
Documentation/devicetree/bindings/regulator/mediatek,mt6316d-regulator.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/regulator/mediatek,mt6316d-regulator.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: MediaTek MT6316 DP/TP SPMI PMIC Regulators 8 + 9 + maintainers: 10 + - AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> 11 + 12 + description: 13 + The MediaTek MT6316DP/TP PMICs are fully controlled by SPMI interface, both 14 + feature four step-down DC/DC (buck) converters, and provides a single Phase, 15 + joining Buck 1+2+3+4. 16 + 17 + properties: 18 + compatible: 19 + const: mediatek,mt6316d-regulator 20 + 21 + reg: 22 + maxItems: 1 23 + 24 + vbuck1234: 25 + type: object 26 + $ref: regulator.yaml# 27 + unevaluatedProperties: false 28 + properties: 29 + regulator-allowed-modes: 30 + description: | 31 + Allowed Buck regulator operating modes allowed. Valid values below. 32 + 0 - Normal mode with automatic power saving, reducing the switching 33 + frequency when light load conditions are detected 34 + 1 - Forced Continuous Conduction mode (FCCM) for improved voltage 35 + regulation accuracy with constant switching frequency but lower 36 + regulator efficiency 37 + 2 - Forced Low Power mode for improved regulator efficiency, used 38 + when no heavy load is expected, will shut down unnecessary IP 39 + blocks and secondary phases to reduce quiescent current. 40 + This mode does not limit the maximum output current but unless 41 + only a light load is applied, there will be regulation accuracy 42 + and efficiency losses. 43 + minItems: 1 44 + maxItems: 3 45 + items: 46 + enum: [ 0, 1, 2 ] 47 + 48 + required: 49 + - compatible 50 + - reg 51 + 52 + additionalProperties: false 53 + 54 + examples: 55 + - | 56 + #include <dt-bindings/spmi/spmi.h> 57 + 58 + spmi { 59 + #address-cells = <2>; 60 + #size-cells = <0>; 61 + 62 + pmic@7 { 63 + compatible = "mediatek,mt6316d-regulator"; 64 + reg = <0x7 SPMI_USID>; 65 + 66 + vbuck1234 { 67 + regulator-name = "dvdd_gpustack"; 68 + regulator-min-microvolt = <400000>; 69 + regulator-max-microvolt = <1277500>; 70 + regulator-allowed-modes = <0 1 2>; 71 + regulator-enable-ramp-delay = <256>; 72 + }; 73 + }; 74 + }; 75 + ...
+146
Documentation/devicetree/bindings/regulator/mediatek,mt6363-regulator.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/regulator/mediatek,mt6363-regulator.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: MediaTek MT6363 PMIC Regulators 8 + 9 + maintainers: 10 + - AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> 11 + 12 + description: 13 + The MT6363 SPMI PMIC provides 10 BUCK and 25 LDO (Low DropOut) regulators 14 + and can optionally provide overcurrent warnings with one ocp interrupt 15 + for each voltage regulator. 16 + 17 + properties: 18 + compatible: 19 + const: mediatek,mt6363-regulator 20 + 21 + reg: 22 + maxItems: 1 23 + 24 + vsys-vbuck1-supply: 25 + description: Input supply for vbuck1 26 + 27 + vsys-vbuck2-supply: 28 + description: Input supply for vbuck2 29 + 30 + vsys-vbuck3-supply: 31 + description: Input supply for vbuck3 32 + 33 + vsys-vbuck4-supply: 34 + description: Input supply for vbuck4 35 + 36 + vsys-vbuck5-supply: 37 + description: Input supply for vbuck5 38 + 39 + vsys-vbuck6-supply: 40 + description: Input supply for vbuck6 41 + 42 + vsys-vbuck7-supply: 43 + description: Input supply for vbuck7 44 + 45 + vsys-vs1-supply: 46 + description: Input supply for vs1 47 + 48 + vsys-vs2-supply: 49 + description: Input supply for vs2 50 + 51 + vsys-vs3-supply: 52 + description: Input supply for vs3 53 + 54 + vs1-ldo1-supply: 55 + description: Input supply for va15, vio0p75, vm18, vrf18, vrf-io18 56 + 57 + vs1-ldo2-supply: 58 + description: Input supply for vcn15, vio18, vufs18 59 + 60 + vs2-ldo1-supply: 61 + description: Input supply for vsram-cpub, vsram-cpum, vrf12, vrf13, vufs12 62 + 63 + vs2-ldo2-supply: 64 + description: Input supply for va12-1, va12-2, vcn13, vsram-cpul 65 + 66 + vs3-ldo1-supply: 67 + description: Input supply for vsram-apu, vsram-digrf, vsram-mdfe 68 + 69 + vs3-ldo2-supply: 70 + description: Input supply for vsram-modem, vrf0p9 71 + 72 + vsys-ldo1-supply: 73 + description: Input supply for vaux18, vemc, vtref18 74 + 75 + patternProperties: 76 + "^v(buck[1-7]|s[1-3])$": 77 + description: Buck regulators 78 + type: object 79 + $ref: regulator.yaml# 80 + unevaluatedProperties: false 81 + properties: 82 + regulator-allowed-modes: 83 + description: | 84 + Allowed Buck regulator operating modes allowed. Valid values below. 85 + 0 - Normal mode with automatic power saving, reducing the switching 86 + frequency when light load conditions are detected 87 + 1 - Forced Continuous Conduction mode (FCCM) for improved voltage 88 + regulation accuracy with constant switching frequency but lower 89 + regulator efficiency 90 + 2 - Forced Low Power mode for improved regulator efficiency, used 91 + when no heavy load is expected, does not limit the maximum out 92 + current but unless only a light load is applied, there will be 93 + regulation accuracy and efficiency losses. 94 + 3 - Forced Ultra Low Power mode for ultra low load, this greatly 95 + reduces the maximum output power, makes the regulator to be 96 + efficient only for ultra light load, and greatly reduces the 97 + quiescent current (Iq) of the buck. 98 + maxItems: 3 99 + items: 100 + enum: [ 0, 1, 2, 3 ] 101 + 102 + "^va(12-1|12-2|15)$": 103 + $ref: "#/$defs/ldo-common" 104 + 105 + "^v(aux|m|rf-io|tref)18$": 106 + $ref: "#/$defs/ldo-common" 107 + 108 + "^v(cn13|cn15|emc)$": 109 + $ref: "#/$defs/ldo-common" 110 + 111 + "^vio(0p75|18)$": 112 + $ref: "#/$defs/ldo-common" 113 + 114 + "^vrf(0p9|12|13|18)$": 115 + $ref: "#/$defs/ldo-common" 116 + 117 + "^vsram-(apu|cpub|cpum|cpul|digrf|mdfe|modem)$": 118 + $ref: "#/$defs/ldo-common" 119 + 120 + "^vufs(12|18)$": 121 + $ref: "#/$defs/ldo-common" 122 + 123 + $defs: 124 + ldo-common: 125 + type: object 126 + $ref: regulator.yaml# 127 + unevaluatedProperties: false 128 + properties: 129 + regulator-allowed-modes: 130 + description: | 131 + Allowed LDO regulator operating modes allowed. Valid values below. 132 + 0 - Normal mode with automatic power saving, reducing the switching 133 + frequency when light load conditions are detected 134 + 2 - Forced Low Power mode for improved regulator efficiency, used 135 + when no heavy load is expected, does not limit the maximum out 136 + current but unless only a light load is applied, there will be 137 + regulation accuracy and efficiency losses. 138 + maxItems: 2 139 + items: 140 + enum: [ 0, 2 ] 141 + 142 + required: 143 + - compatible 144 + - reg 145 + 146 + additionalProperties: false
+20
drivers/regulator/Kconfig
··· 881 881 This driver supports the control of different power rails of device 882 882 through regulator interface. 883 883 884 + config REGULATOR_MT6316 885 + tristate "MT6316 SPMI PMIC regulator driver" 886 + depends on SPMI 887 + select REGMAP_SPMI 888 + help 889 + Say Y here to enable support for 2+2, 3+1 and 4 phase regulators 890 + found in the MediaTek MT6316 BP, CP, DP, HP, VP and TP SPMI PMICs. 891 + This driver supports the control of different power rails of device 892 + through regulator interface. 893 + 884 894 config REGULATOR_MT6323 885 895 tristate "MediaTek MT6323 PMIC" 886 896 depends on MFD_MT6397 ··· 953 943 This is support MT6360 PMIC/LDO part include 954 944 2-channel buck with Thermal Shutdown and Overload Protection 955 945 6-channel High PSRR and Low Dropout LDO. 946 + 947 + config REGULATOR_MT6363 948 + tristate "MT6363 SPMI PMIC regulator driver" 949 + depends on SPMI 950 + select REGMAP_SPMI 951 + help 952 + Say Y here to enable support for regulators found in the MediaTek 953 + MT6363 SPMI PMIC. 954 + This driver supports the control of different power rails of device 955 + through regulator interface. 956 956 957 957 config REGULATOR_MT6370 958 958 tristate "MT6370 SubPMIC Regulator"
+2
drivers/regulator/Makefile
··· 105 105 obj-$(CONFIG_REGULATOR_MPQ7920) += mpq7920.o 106 106 obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o 107 107 obj-$(CONFIG_REGULATOR_MT6315) += mt6315-regulator.o 108 + obj-$(CONFIG_REGULATOR_MT6315) += mt6316-regulator.o 108 109 obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o 109 110 obj-$(CONFIG_REGULATOR_MT6331) += mt6331-regulator.o 110 111 obj-$(CONFIG_REGULATOR_MT6332) += mt6332-regulator.o ··· 113 112 obj-$(CONFIG_REGULATOR_MT6358) += mt6358-regulator.o 114 113 obj-$(CONFIG_REGULATOR_MT6359) += mt6359-regulator.o 115 114 obj-$(CONFIG_REGULATOR_MT6360) += mt6360-regulator.o 115 + obj-$(CONFIG_REGULATOR_MT6363) += mt6363-regulator.o 116 116 obj-$(CONFIG_REGULATOR_MT6370) += mt6370-regulator.o 117 117 obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o 118 118 obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
+345
drivers/regulator/mt6316-regulator.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // Copyright (c) 2024 MediaTek Inc. 4 + // Copyright (c) 2025 Collabora Ltd 5 + // AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> 6 + 7 + #include <linux/module.h> 8 + #include <linux/of.h> 9 + #include <linux/regmap.h> 10 + #include <linux/spmi.h> 11 + 12 + #include <linux/regulator/driver.h> 13 + #include <linux/regulator/machine.h> 14 + #include <linux/regulator/of_regulator.h> 15 + 16 + #define MT6316_BUCK_MODE_AUTO 0 17 + #define MT6316_BUCK_MODE_FORCE_PWM 1 18 + #define MT6316_BUCK_MODE_LP 2 19 + 20 + #define MT6316_CHIP_ID 0x20b 21 + #define MT6316_BUCK_TOP_CON0 0x1440 22 + #define EN_SET_OFFSET 0x1 23 + #define EN_CLR_OFFSET 0x2 24 + 25 + #define MT6316_BUCK_TOP_CON1 0x1443 26 + 27 + #define MT6316_BUCK_TOP_ELR0 0x1448 28 + #define MT6316_BUCK_TOP_ELR2 0x144a 29 + #define MT6316_BUCK_TOP_ELR4 0x144c 30 + #define MT6316_BUCK_TOP_ELR6 0x144e 31 + #define MT6316_VSEL_MASK GENMASK(8, 0) 32 + 33 + #define MT6316_VBUCK1_DBG 0x14a8 34 + #define MT6316_VBUCK2_DBG 0x1528 35 + #define MT6316_VBUCK3_DBG 0x15a8 36 + #define MT6316_VBUCK4_DBG 0x1628 37 + #define MT6316_BUCK_QI BIT(0) 38 + 39 + #define MT6316_BUCK_TOP_4PHASE_TOP_ANA_CON0 0x1688 40 + #define MT6316_BUCK_TOP_4PHASE_TOP_ELR_0 0x1690 41 + 42 + enum mt6316_type { 43 + MT6316_TYPE_2PHASE, 44 + MT6316_TYPE_3PHASE, 45 + MT6316_TYPE_4PHASE 46 + }; 47 + 48 + /** 49 + * struct mt6316_regulator_info - MT6316 regulators information 50 + * @desc: Regulator description structure 51 + * @debug_reg: Debug register for regulator status 52 + * @lp_mode_reg: Low Power mode register (normal/idle) 53 + * @lp_mode_mask: Low Power mode regulator mask 54 + * @modeset_reg: AUTO/PWM mode register 55 + * @modeset_mask: AUTO/PWM regulator mask 56 + */ 57 + struct mt6316_regulator_info { 58 + struct regulator_desc desc; 59 + u16 debug_reg; 60 + u16 lp_mode_reg; 61 + u16 lp_mode_mask; 62 + u16 modeset_reg; 63 + u16 modeset_mask; 64 + }; 65 + 66 + #define MT6316_BUCK(match, vreg_id, min, max, step, vs_reg) \ 67 + { \ 68 + .desc = { \ 69 + .name = match, \ 70 + .of_match = of_match_ptr(match), \ 71 + .ops = &mt6316_vreg_setclr_ops, \ 72 + .type = REGULATOR_VOLTAGE, \ 73 + .owner = THIS_MODULE, \ 74 + .n_voltages = (max - min) / step + 1, \ 75 + .min_uV = min, \ 76 + .uV_step = step, \ 77 + .enable_reg = MT6316_BUCK_TOP_CON0, \ 78 + .enable_mask = BIT(vreg_id - 1), \ 79 + .vsel_reg = vs_reg, \ 80 + .vsel_mask = MT6316_VSEL_MASK, \ 81 + .of_map_mode = mt6316_map_mode, \ 82 + }, \ 83 + .lp_mode_reg = MT6316_BUCK_TOP_CON1, \ 84 + .lp_mode_mask = BIT(vreg_id - 1), \ 85 + .modeset_reg = MT6316_BUCK_TOP_4PHASE_TOP_ANA_CON0, \ 86 + .modeset_mask = BIT(vreg_id - 1), \ 87 + .debug_reg = MT6316_VBUCK##vreg_id##_DBG, \ 88 + } 89 + 90 + /* Values in some MT6316 registers are big endian, 9 bits long... */ 91 + static inline u16 mt6316_be9_to_cpu(u16 val) 92 + { 93 + return ((val >> 8) & BIT(0)) | ((val & GENMASK(7, 0)) << 1); 94 + } 95 + 96 + static inline u16 mt6316_cpu_to_be9(u16 val) 97 + { 98 + return ((val & BIT(0)) << 8) | (val >> 1); 99 + } 100 + 101 + static unsigned int mt6316_map_mode(u32 mode) 102 + { 103 + switch (mode) { 104 + case MT6316_BUCK_MODE_AUTO: 105 + return REGULATOR_MODE_NORMAL; 106 + case MT6316_BUCK_MODE_FORCE_PWM: 107 + return REGULATOR_MODE_FAST; 108 + case MT6316_BUCK_MODE_LP: 109 + return REGULATOR_MODE_IDLE; 110 + default: 111 + return REGULATOR_MODE_INVALID; 112 + } 113 + } 114 + 115 + static int mt6316_vreg_enable_setclr(struct regulator_dev *rdev) 116 + { 117 + return regmap_write(rdev->regmap, rdev->desc->enable_reg + EN_SET_OFFSET, 118 + rdev->desc->enable_mask); 119 + } 120 + 121 + static int mt6316_vreg_disable_setclr(struct regulator_dev *rdev) 122 + { 123 + return regmap_write(rdev->regmap, rdev->desc->enable_reg + EN_CLR_OFFSET, 124 + rdev->desc->enable_mask); 125 + } 126 + 127 + static int mt6316_regulator_set_voltage_sel(struct regulator_dev *rdev, unsigned int selector) 128 + { 129 + u16 val = mt6316_cpu_to_be9(selector); 130 + 131 + return regmap_bulk_write(rdev->regmap, rdev->desc->vsel_reg, &val, sizeof(val)); 132 + } 133 + 134 + static int mt6316_regulator_get_voltage_sel(struct regulator_dev *rdev) 135 + { 136 + u16 val; 137 + int ret; 138 + 139 + ret = regmap_bulk_read(rdev->regmap, rdev->desc->vsel_reg, &val, sizeof(val)); 140 + if (ret) 141 + return ret; 142 + 143 + return mt6316_be9_to_cpu(val & rdev->desc->vsel_mask); 144 + } 145 + 146 + static int mt6316_regulator_get_status(struct regulator_dev *rdev) 147 + { 148 + struct mt6316_regulator_info *info = rdev_get_drvdata(rdev); 149 + u32 val; 150 + int ret; 151 + 152 + ret = regmap_read(rdev->regmap, info->debug_reg, &val); 153 + if (ret) 154 + return ret; 155 + 156 + return val & MT6316_BUCK_QI ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF; 157 + } 158 + 159 + static unsigned int mt6316_regulator_get_mode(struct regulator_dev *rdev) 160 + { 161 + struct mt6316_regulator_info *info = rdev_get_drvdata(rdev); 162 + unsigned int val; 163 + int ret; 164 + 165 + ret = regmap_read(rdev->regmap, info->modeset_reg, &val); 166 + if (ret) { 167 + dev_err(&rdev->dev, "Failed to get mode: %d\n", ret); 168 + return ret; 169 + } 170 + 171 + if ((val & info->modeset_mask) == info->modeset_mask) 172 + return REGULATOR_MODE_FAST; 173 + 174 + ret = regmap_read(rdev->regmap, info->lp_mode_reg, &val); 175 + val &= info->lp_mode_mask; 176 + if (ret) { 177 + dev_err(&rdev->dev, "Failed to get lp mode: %d\n", ret); 178 + return ret; 179 + } 180 + 181 + return val ? REGULATOR_MODE_IDLE : REGULATOR_MODE_NORMAL; 182 + } 183 + 184 + static int mt6316_regulator_set_mode(struct regulator_dev *rdev, 185 + unsigned int mode) 186 + { 187 + struct mt6316_regulator_info *info = rdev_get_drvdata(rdev); 188 + struct regmap *regmap = rdev->regmap; 189 + int cur_mode, ret; 190 + 191 + switch (mode) { 192 + case REGULATOR_MODE_FAST: 193 + ret = regmap_set_bits(regmap, info->modeset_reg, info->modeset_mask); 194 + break; 195 + case REGULATOR_MODE_NORMAL: 196 + cur_mode = mt6316_regulator_get_mode(rdev); 197 + if (cur_mode < 0) { 198 + ret = cur_mode; 199 + break; 200 + } 201 + 202 + if (cur_mode == REGULATOR_MODE_FAST) { 203 + ret = regmap_clear_bits(regmap, info->modeset_reg, info->modeset_mask); 204 + break; 205 + } else if (cur_mode == REGULATOR_MODE_IDLE) { 206 + ret = regmap_clear_bits(regmap, info->lp_mode_reg, info->lp_mode_mask); 207 + if (ret == 0) 208 + usleep_range(100, 200); 209 + } else { 210 + ret = 0; 211 + } 212 + break; 213 + case REGULATOR_MODE_IDLE: 214 + ret = regmap_set_bits(regmap, info->lp_mode_reg, info->lp_mode_mask); 215 + break; 216 + default: 217 + ret = -EINVAL; 218 + } 219 + 220 + if (ret) { 221 + dev_err(&rdev->dev, "Failed to set mode %u: %d\n", mode, ret); 222 + return ret; 223 + } 224 + 225 + return 0; 226 + } 227 + 228 + static const struct regulator_ops mt6316_vreg_setclr_ops = { 229 + .list_voltage = regulator_list_voltage_linear, 230 + .map_voltage = regulator_map_voltage_linear, 231 + .set_voltage_sel = mt6316_regulator_set_voltage_sel, 232 + .get_voltage_sel = mt6316_regulator_get_voltage_sel, 233 + .set_voltage_time_sel = regulator_set_voltage_time_sel, 234 + .enable = mt6316_vreg_enable_setclr, 235 + .disable = mt6316_vreg_disable_setclr, 236 + .is_enabled = regulator_is_enabled_regmap, 237 + .get_status = mt6316_regulator_get_status, 238 + .set_mode = mt6316_regulator_set_mode, 239 + .get_mode = mt6316_regulator_get_mode, 240 + }; 241 + 242 + /* MT6316BP/VP - 2+2 phase buck */ 243 + static struct mt6316_regulator_info mt6316bv_regulators[] = { 244 + MT6316_BUCK("vbuck12", 1, 0, 1277500, 2500, MT6316_BUCK_TOP_ELR0), 245 + MT6316_BUCK("vbuck34", 3, 0, 1277500, 2500, MT6316_BUCK_TOP_ELR4), 246 + }; 247 + 248 + /* MT6316CP/HP/KP - 3+1 phase buck */ 249 + static struct mt6316_regulator_info mt6316chk_regulators[] = { 250 + MT6316_BUCK("vbuck124", 1, 0, 1277500, 2500, MT6316_BUCK_TOP_ELR0), 251 + MT6316_BUCK("vbuck3", 3, 0, 1277500, 2500, MT6316_BUCK_TOP_ELR4), 252 + }; 253 + 254 + /* MT6316DP/TP - 4 phase buck */ 255 + static struct mt6316_regulator_info mt6316dt_regulators[] = { 256 + MT6316_BUCK("vbuck1234", 1, 0, 1277500, 2500, MT6316_BUCK_TOP_ELR0), 257 + }; 258 + 259 + static const struct regmap_config mt6316_spmi_regmap_config = { 260 + .reg_bits = 16, 261 + .val_bits = 8, 262 + .max_register = 0x1700, 263 + .fast_io = true, 264 + }; 265 + 266 + static int mt6316_regulator_probe(struct spmi_device *sdev) 267 + { 268 + struct regulator_config config = {}; 269 + struct mt6316_regulator_info *info; 270 + struct regulator_dev *rdev; 271 + enum mt6316_type type; 272 + int num_vregs, ret; 273 + unsigned int i; 274 + u32 chip_id; 275 + 276 + config.regmap = devm_regmap_init_spmi_ext(sdev, &mt6316_spmi_regmap_config); 277 + if (IS_ERR(config.regmap)) 278 + return PTR_ERR(config.regmap); 279 + 280 + /* 281 + * The first read is expected to fail: this PMIC needs to be woken up 282 + * and that can be done with any activity over the SPMI bus. 283 + */ 284 + regmap_read(config.regmap, MT6316_CHIP_ID, &chip_id); 285 + 286 + /* The second read, instead, shall not fail! */ 287 + ret = regmap_read(config.regmap, MT6316_CHIP_ID, &chip_id); 288 + if (ret) { 289 + dev_err(&sdev->dev, "Cannot read Chip ID!\n"); 290 + return ret; 291 + } 292 + dev_dbg(&sdev->dev, "Chip ID: 0x%x\n", chip_id); 293 + 294 + config.dev = &sdev->dev; 295 + 296 + type = (uintptr_t)device_get_match_data(&sdev->dev); 297 + switch (type) { 298 + case MT6316_TYPE_2PHASE: 299 + info = mt6316bv_regulators; 300 + num_vregs = ARRAY_SIZE(mt6316bv_regulators); 301 + break; 302 + case MT6316_TYPE_3PHASE: 303 + info = mt6316chk_regulators; 304 + num_vregs = ARRAY_SIZE(mt6316chk_regulators); 305 + break; 306 + case MT6316_TYPE_4PHASE: 307 + info = mt6316dt_regulators; 308 + num_vregs = ARRAY_SIZE(mt6316dt_regulators); 309 + break; 310 + default: 311 + return -EINVAL; 312 + } 313 + 314 + for (i = 0; i < num_vregs; i++) { 315 + config.driver_data = &info[i]; 316 + 317 + rdev = devm_regulator_register(&sdev->dev, &info[i].desc, &config); 318 + if (IS_ERR(rdev)) 319 + return dev_err_probe(&sdev->dev, PTR_ERR(rdev), 320 + "failed to register %s\n", info[i].desc.name); 321 + } 322 + 323 + return 0; 324 + } 325 + 326 + static const struct of_device_id mt6316_regulator_match[] = { 327 + { .compatible = "mediatek,mt6316b-regulator", .data = (void *)MT6316_TYPE_2PHASE }, 328 + { .compatible = "mediatek,mt6316c-regulator", .data = (void *)MT6316_TYPE_3PHASE }, 329 + { .compatible = "mediatek,mt6316d-regulator", .data = (void *)MT6316_TYPE_4PHASE }, 330 + { /* sentinel */ } 331 + }; 332 + 333 + static struct spmi_driver mt6316_regulator_driver = { 334 + .driver = { 335 + .name = "mt6316-regulator", 336 + .probe_type = PROBE_PREFER_ASYNCHRONOUS, 337 + .of_match_table = mt6316_regulator_match, 338 + }, 339 + .probe = mt6316_regulator_probe, 340 + }; 341 + module_spmi_driver(mt6316_regulator_driver); 342 + 343 + MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>"); 344 + MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6316 PMIC"); 345 + MODULE_LICENSE("GPL");
+938
drivers/regulator/mt6363-regulator.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // Copyright (c) 2024 MediaTek Inc. 4 + // Copyright (c) 2025 Collabora Ltd 5 + // AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> 6 + 7 + #include <linux/bitfield.h> 8 + #include <linux/delay.h> 9 + #include <linux/devm-helpers.h> 10 + #include <linux/err.h> 11 + #include <linux/interrupt.h> 12 + #include <linux/irq.h> 13 + #include <linux/irqdomain.h> 14 + #include <linux/kernel.h> 15 + #include <linux/module.h> 16 + #include <linux/of.h> 17 + #include <linux/of_device.h> 18 + #include <linux/of_irq.h> 19 + #include <linux/platform_device.h> 20 + #include <linux/regmap.h> 21 + #include <linux/spmi.h> 22 + 23 + #include <linux/regulator/driver.h> 24 + #include <linux/regulator/machine.h> 25 + #include <linux/regulator/mt6363-regulator.h> 26 + #include <linux/regulator/of_regulator.h> 27 + 28 + #define MT6363_REGULATOR_MODE_NORMAL 0 29 + #define MT6363_REGULATOR_MODE_FCCM 1 30 + #define MT6363_REGULATOR_MODE_LP 2 31 + #define MT6363_REGULATOR_MODE_ULP 3 32 + 33 + #define EN_SET_OFFSET 0x1 34 + #define EN_CLR_OFFSET 0x2 35 + #define OP_CFG_OFFSET 0x5 36 + 37 + #define NORMAL_OP_CFG 0x10 38 + #define NORMAL_OP_EN 0x800000 39 + 40 + #define OC_IRQ_ENABLE_DELAY_MS 10 41 + 42 + /* Unlock keys for TMA and BUCK_TOP */ 43 + #define MT6363_TMA_UNLOCK_VALUE 0x9c9c 44 + #define MT6363_BUCK_TOP_UNLOCK_VALUE 0x5543 45 + 46 + enum { 47 + MT6363_ID_VBUCK1, 48 + MT6363_ID_VBUCK2, 49 + MT6363_ID_VBUCK3, 50 + MT6363_ID_VBUCK4, 51 + MT6363_ID_VBUCK5, 52 + MT6363_ID_VBUCK6, 53 + MT6363_ID_VBUCK7, 54 + MT6363_ID_VS1, 55 + MT6363_ID_VS2, 56 + MT6363_ID_VS3, 57 + MT6363_ID_VA12_1, 58 + MT6363_ID_VA12_2, 59 + MT6363_ID_VA15, 60 + MT6363_ID_VAUX18, 61 + MT6363_ID_VCN13, 62 + MT6363_ID_VCN15, 63 + MT6363_ID_VEMC, 64 + MT6363_ID_VIO075, 65 + MT6363_ID_VIO18, 66 + MT6363_ID_VM18, 67 + MT6363_ID_VSRAM_APU, 68 + MT6363_ID_VSRAM_CPUB, 69 + MT6363_ID_VSRAM_CPUM, 70 + MT6363_ID_VSRAM_CPUL, 71 + MT6363_ID_VSRAM_DIGRF, 72 + MT6363_ID_VSRAM_MDFE, 73 + MT6363_ID_VSRAM_MODEM, 74 + MT6363_ID_VRF09, 75 + MT6363_ID_VRF12, 76 + MT6363_ID_VRF13, 77 + MT6363_ID_VRF18, 78 + MT6363_ID_VRFIO18, 79 + MT6363_ID_VTREF18, 80 + MT6363_ID_VUFS12, 81 + MT6363_ID_VUFS18, 82 + }; 83 + 84 + /** 85 + * struct mt6363_regulator_info - MT6363 regulators information 86 + * @desc: Regulator description structure 87 + * @lp_mode_reg: Low Power mode register (normal/idle) 88 + * @lp_mode_mask: Low Power mode regulator mask 89 + * @hw_lp_mode_reg: Hardware voted Low Power mode register (normal/idle) 90 + * @hw_lp_mode_mask: Hardware voted Low Power mode regulator mask 91 + * @modeset_reg: AUTO/PWM mode register 92 + * @modeset_mask: AUTO/PWM regulator mask 93 + * @lp_imax_uA: Maximum load current (microamps), for Low Power mode only 94 + * @op_en_reg: Operation mode enablement register 95 + * @orig_op_en: Backup of a regulator's operation mode enablement register 96 + * @orig_op_cfg: Backup of a regulator's operation mode configuration register 97 + * @oc_work: Delayed work for enabling overcurrent IRQ 98 + * @hwirq: PMIC-Internal HW Interrupt for overcurrent event 99 + * @virq: Mapped Interrupt for overcurrent event 100 + */ 101 + struct mt6363_regulator_info { 102 + struct regulator_desc desc; 103 + u16 lp_mode_reg; 104 + u16 lp_mode_mask; 105 + u16 hw_lp_mode_reg; 106 + u16 hw_lp_mode_mask; 107 + u16 modeset_reg; 108 + u16 modeset_mask; 109 + int lp_imax_uA; 110 + u16 op_en_reg; 111 + u32 orig_op_en; 112 + u8 orig_op_cfg; 113 + struct delayed_work oc_work; 114 + u8 hwirq; 115 + int virq; 116 + }; 117 + 118 + #define MT6363_BUCK(match, vreg, min, max, step, en_reg, lp_reg, \ 119 + mset_reg, ocp_intn) \ 120 + [MT6363_ID_##vreg] = { \ 121 + .desc = { \ 122 + .name = match, \ 123 + .supply_name = "vsys-"match, \ 124 + .of_match = of_match_ptr(match), \ 125 + .ops = &mt6363_vreg_setclr_ops, \ 126 + .type = REGULATOR_VOLTAGE, \ 127 + .id = MT6363_ID_##vreg, \ 128 + .owner = THIS_MODULE, \ 129 + .n_voltages = (max - min) / step + 1, \ 130 + .min_uV = min, \ 131 + .uV_step = step, \ 132 + .enable_reg = en_reg, \ 133 + .enable_mask = BIT(MT6363_RG_BUCK_##vreg##_EN_BIT), \ 134 + .vsel_reg = MT6363_RG_BUCK_##vreg##_VOSEL_ADDR, \ 135 + .vsel_mask = MT6363_RG_BUCK_##vreg##_VOSEL_MASK, \ 136 + .of_map_mode = mt6363_map_mode, \ 137 + }, \ 138 + .lp_mode_reg = lp_reg, \ 139 + .lp_mode_mask = BIT(MT6363_RG_BUCK_##vreg##_LP_BIT), \ 140 + .hw_lp_mode_reg = MT6363_BUCK_##vreg##_HW_LP_MODE, \ 141 + .hw_lp_mode_mask = 0xc, \ 142 + .modeset_reg = mset_reg, \ 143 + .modeset_mask = BIT(MT6363_RG_##vreg##_FCCM_BIT), \ 144 + .lp_imax_uA = 100000, \ 145 + .op_en_reg = MT6363_BUCK_##vreg##_OP_EN_0, \ 146 + .hwirq = ocp_intn, \ 147 + } 148 + 149 + #define MT6363_LDO_LINEAR_OPS(match, vreg, in_sup, vops, min, max, \ 150 + step, buck_reg, ocp_intn) \ 151 + [MT6363_ID_##vreg] = { \ 152 + .desc = { \ 153 + .name = match, \ 154 + .supply_name = in_sup, \ 155 + .of_match = of_match_ptr(match), \ 156 + .ops = &vops, \ 157 + .type = REGULATOR_VOLTAGE, \ 158 + .id = MT6363_ID_##vreg, \ 159 + .owner = THIS_MODULE, \ 160 + .n_voltages = (max - min) / step + 1, \ 161 + .min_uV = min, \ 162 + .uV_step = step, \ 163 + .enable_reg = MT6363_RG_##buck_reg##_EN_ADDR, \ 164 + .enable_mask = BIT(MT6363_RG_LDO_##vreg##_EN_BIT), \ 165 + .vsel_reg = MT6363_RG_LDO_##vreg##_VOSEL_ADDR, \ 166 + .vsel_mask = MT6363_RG_LDO_##vreg##_VOSEL_MASK, \ 167 + .of_map_mode = mt6363_map_mode, \ 168 + }, \ 169 + .lp_mode_reg = MT6363_RG_##buck_reg##_LP_ADDR, \ 170 + .lp_mode_mask = BIT(MT6363_RG_LDO_##vreg##_LP_BIT), \ 171 + .hw_lp_mode_reg = MT6363_LDO_##vreg##_HW_LP_MODE, \ 172 + .hw_lp_mode_mask = 0x4, \ 173 + .hwirq = ocp_intn, \ 174 + } 175 + 176 + #define MT6363_LDO_L_SC(match, vreg, inp, min, max, step, buck_reg, \ 177 + ocp_intn) \ 178 + MT6363_LDO_LINEAR_OPS(match, vreg, inp, mt6363_vreg_setclr_ops, \ 179 + min, max, step, buck_reg, ocp_intn) 180 + 181 + #define MT6363_LDO_L(match, vreg, inp, min, max, step, buck_reg, \ 182 + ocp_intn) \ 183 + MT6363_LDO_LINEAR_OPS(match, vreg, inp, mt6363_ldo_linear_ops, \ 184 + min, max, step, buck_reg, ocp_intn) 185 + 186 + #define MT6363_LDO_LINEAR_CAL_OPS(match, vreg, in_sup, vops, vrnum, \ 187 + ocp_intn) \ 188 + [MT6363_ID_##vreg] = { \ 189 + .desc = { \ 190 + .name = match, \ 191 + .supply_name = in_sup, \ 192 + .of_match = of_match_ptr(match), \ 193 + .ops = &vops, \ 194 + .type = REGULATOR_VOLTAGE, \ 195 + .id = MT6363_ID_##vreg, \ 196 + .owner = THIS_MODULE, \ 197 + .n_voltages = ARRAY_SIZE(ldo_volt_ranges##vrnum) * 11, \ 198 + .linear_ranges = ldo_volt_ranges##vrnum, \ 199 + .n_linear_ranges = ARRAY_SIZE(ldo_volt_ranges##vrnum), \ 200 + .linear_range_selectors_bitfield = ldos_cal_selectors, \ 201 + .enable_reg = MT6363_RG_LDO_##vreg##_ADDR, \ 202 + .enable_mask = BIT(MT6363_RG_LDO_##vreg##_EN_BIT), \ 203 + .vsel_reg = MT6363_RG_##vreg##_VOCAL_ADDR, \ 204 + .vsel_mask = MT6363_RG_##vreg##_VOCAL_MASK, \ 205 + .vsel_range_reg = MT6363_RG_##vreg##_VOSEL_ADDR, \ 206 + .vsel_range_mask = MT6363_RG_##vreg##_VOSEL_MASK, \ 207 + .of_map_mode = mt6363_map_mode, \ 208 + }, \ 209 + .lp_mode_reg = MT6363_RG_LDO_##vreg##_ADDR, \ 210 + .lp_mode_mask = BIT(MT6363_RG_LDO_##vreg##_LP_BIT), \ 211 + .hw_lp_mode_reg = MT6363_LDO_##vreg##_HW_LP_MODE, \ 212 + .hw_lp_mode_mask = 0x4, \ 213 + .lp_imax_uA = 10000, \ 214 + .op_en_reg = MT6363_LDO_##vreg##_OP_EN0, \ 215 + .hwirq = ocp_intn, \ 216 + } 217 + 218 + #define MT6363_LDO_VT(match, vreg, inp, vranges_num, ocp_intn) \ 219 + MT6363_LDO_LINEAR_CAL_OPS(match, vreg, inp, mt6363_ldo_vtable_ops,\ 220 + vranges_num, ocp_intn) 221 + 222 + static const unsigned int ldos_cal_selectors[] = { 223 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 224 + }; 225 + 226 + static const struct linear_range ldo_volt_ranges0[] = { 227 + REGULATOR_LINEAR_RANGE(1200000, 0, 10, 10000), 228 + REGULATOR_LINEAR_RANGE(1300000, 0, 10, 10000), 229 + REGULATOR_LINEAR_RANGE(1500000, 0, 10, 10000), 230 + REGULATOR_LINEAR_RANGE(1700000, 0, 10, 10000), 231 + REGULATOR_LINEAR_RANGE(1800000, 0, 10, 10000), 232 + REGULATOR_LINEAR_RANGE(2000000, 0, 10, 10000), 233 + REGULATOR_LINEAR_RANGE(2500000, 0, 10, 10000), 234 + REGULATOR_LINEAR_RANGE(2600000, 0, 10, 10000), 235 + REGULATOR_LINEAR_RANGE(2700000, 0, 10, 10000), 236 + REGULATOR_LINEAR_RANGE(2800000, 0, 10, 10000), 237 + REGULATOR_LINEAR_RANGE(2900000, 0, 10, 10000), 238 + REGULATOR_LINEAR_RANGE(3000000, 0, 10, 10000), 239 + REGULATOR_LINEAR_RANGE(3100000, 0, 10, 10000), 240 + REGULATOR_LINEAR_RANGE(3300000, 0, 10, 10000), 241 + REGULATOR_LINEAR_RANGE(3400000, 0, 10, 10000), 242 + REGULATOR_LINEAR_RANGE(3500000, 0, 10, 10000) 243 + }; 244 + 245 + static const struct linear_range ldo_volt_ranges1[] = { 246 + REGULATOR_LINEAR_RANGE(900000, 0, 10, 10000), 247 + REGULATOR_LINEAR_RANGE(1000000, 0, 10, 10000), 248 + REGULATOR_LINEAR_RANGE(1100000, 0, 10, 10000), 249 + REGULATOR_LINEAR_RANGE(1200000, 0, 10, 10000), 250 + REGULATOR_LINEAR_RANGE(1300000, 0, 10, 10000), 251 + REGULATOR_LINEAR_RANGE(1700000, 0, 10, 10000), 252 + REGULATOR_LINEAR_RANGE(1800000, 0, 10, 10000), 253 + REGULATOR_LINEAR_RANGE(1810000, 0, 10, 10000) 254 + }; 255 + 256 + static const struct linear_range ldo_volt_ranges2[] = { 257 + REGULATOR_LINEAR_RANGE(1800000, 0, 10, 10000), 258 + REGULATOR_LINEAR_RANGE(1900000, 0, 10, 10000), 259 + REGULATOR_LINEAR_RANGE(2000000, 0, 10, 10000), 260 + REGULATOR_LINEAR_RANGE(2100000, 0, 10, 10000), 261 + REGULATOR_LINEAR_RANGE(2200000, 0, 10, 10000), 262 + REGULATOR_LINEAR_RANGE(2300000, 0, 10, 10000), 263 + REGULATOR_LINEAR_RANGE(2400000, 0, 10, 10000), 264 + REGULATOR_LINEAR_RANGE(2500000, 0, 10, 10000), 265 + REGULATOR_LINEAR_RANGE(2600000, 0, 10, 10000), 266 + REGULATOR_LINEAR_RANGE(2700000, 0, 10, 10000), 267 + REGULATOR_LINEAR_RANGE(2800000, 0, 10, 10000), 268 + REGULATOR_LINEAR_RANGE(2900000, 0, 10, 10000), 269 + REGULATOR_LINEAR_RANGE(3000000, 0, 10, 10000), 270 + REGULATOR_LINEAR_RANGE(3100000, 0, 10, 10000), 271 + REGULATOR_LINEAR_RANGE(3200000, 0, 10, 10000), 272 + REGULATOR_LINEAR_RANGE(3300000, 0, 10, 10000) 273 + }; 274 + 275 + static const struct linear_range ldo_volt_ranges3[] = { 276 + REGULATOR_LINEAR_RANGE(600000, 0, 10, 10000), 277 + REGULATOR_LINEAR_RANGE(700000, 0, 10, 10000), 278 + REGULATOR_LINEAR_RANGE(800000, 0, 10, 10000), 279 + REGULATOR_LINEAR_RANGE(900000, 0, 10, 10000), 280 + REGULATOR_LINEAR_RANGE(1000000, 0, 10, 10000), 281 + REGULATOR_LINEAR_RANGE(1100000, 0, 10, 10000), 282 + REGULATOR_LINEAR_RANGE(1200000, 0, 10, 10000), 283 + REGULATOR_LINEAR_RANGE(1300000, 0, 10, 10000), 284 + REGULATOR_LINEAR_RANGE(1400000, 0, 10, 10000), 285 + REGULATOR_LINEAR_RANGE(1500000, 0, 10, 10000), 286 + REGULATOR_LINEAR_RANGE(1600000, 0, 10, 10000), 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 + REGULATOR_LINEAR_RANGE(2000000, 0, 10, 10000), 291 + REGULATOR_LINEAR_RANGE(2100000, 0, 10, 10000) 292 + }; 293 + 294 + static const struct linear_range ldo_volt_ranges4[] = { 295 + REGULATOR_LINEAR_RANGE(550000, 0, 10, 5000), 296 + REGULATOR_LINEAR_RANGE(600000, 0, 10, 5000), 297 + REGULATOR_LINEAR_RANGE(650000, 0, 10, 5000), 298 + REGULATOR_LINEAR_RANGE(700000, 0, 10, 5000), 299 + REGULATOR_LINEAR_RANGE(750000, 0, 10, 5000), 300 + REGULATOR_LINEAR_RANGE(800000, 0, 10, 5000), 301 + REGULATOR_LINEAR_RANGE(900000, 0, 10, 5000), 302 + REGULATOR_LINEAR_RANGE(950000, 0, 10, 5000), 303 + REGULATOR_LINEAR_RANGE(1000000, 0, 10, 5000), 304 + REGULATOR_LINEAR_RANGE(1050000, 0, 10, 5000), 305 + REGULATOR_LINEAR_RANGE(1100000, 0, 10, 5000), 306 + REGULATOR_LINEAR_RANGE(1150000, 0, 10, 5000), 307 + REGULATOR_LINEAR_RANGE(1700000, 0, 10, 5000), 308 + REGULATOR_LINEAR_RANGE(1750000, 0, 10, 5000), 309 + REGULATOR_LINEAR_RANGE(1800000, 0, 10, 5000), 310 + REGULATOR_LINEAR_RANGE(1850000, 0, 10, 5000) 311 + }; 312 + 313 + static const struct linear_range ldo_volt_ranges5[] = { 314 + REGULATOR_LINEAR_RANGE(600000, 0, 10, 5000), 315 + REGULATOR_LINEAR_RANGE(650000, 0, 10, 5000), 316 + REGULATOR_LINEAR_RANGE(700000, 0, 10, 5000), 317 + REGULATOR_LINEAR_RANGE(750000, 0, 10, 5000), 318 + REGULATOR_LINEAR_RANGE(800000, 0, 10, 5000) 319 + }; 320 + 321 + static int mt6363_vreg_enable_setclr(struct regulator_dev *rdev) 322 + { 323 + return regmap_write(rdev->regmap, rdev->desc->enable_reg + EN_SET_OFFSET, 324 + rdev->desc->enable_mask); 325 + } 326 + 327 + static int mt6363_vreg_disable_setclr(struct regulator_dev *rdev) 328 + { 329 + return regmap_write(rdev->regmap, rdev->desc->enable_reg + EN_CLR_OFFSET, 330 + rdev->desc->enable_mask); 331 + } 332 + 333 + static inline unsigned int mt6363_map_mode(unsigned int mode) 334 + { 335 + switch (mode) { 336 + case MT6363_REGULATOR_MODE_NORMAL: 337 + return REGULATOR_MODE_NORMAL; 338 + case MT6363_REGULATOR_MODE_FCCM: 339 + return REGULATOR_MODE_FAST; 340 + case MT6363_REGULATOR_MODE_LP: 341 + return REGULATOR_MODE_IDLE; 342 + case MT6363_REGULATOR_MODE_ULP: 343 + return REGULATOR_MODE_STANDBY; 344 + default: 345 + return REGULATOR_MODE_INVALID; 346 + } 347 + } 348 + 349 + static unsigned int mt6363_regulator_get_mode(struct regulator_dev *rdev) 350 + { 351 + struct mt6363_regulator_info *info = rdev_get_drvdata(rdev); 352 + unsigned int val; 353 + int ret; 354 + 355 + if (info->modeset_reg) { 356 + ret = regmap_read(rdev->regmap, info->modeset_reg, &val); 357 + if (ret) { 358 + dev_err(&rdev->dev, "Failed to get mt6363 mode: %d\n", ret); 359 + return ret; 360 + } 361 + 362 + if (val & info->modeset_mask) 363 + return REGULATOR_MODE_FAST; 364 + } else { 365 + val = 0; 366 + }; 367 + 368 + ret = regmap_read(rdev->regmap, info->hw_lp_mode_reg, &val); 369 + val &= info->hw_lp_mode_mask; 370 + 371 + if (ret) { 372 + dev_err(&rdev->dev, "Failed to get lp mode: %d\n", ret); 373 + return ret; 374 + } 375 + 376 + if (val) 377 + return REGULATOR_MODE_IDLE; 378 + else 379 + return REGULATOR_MODE_NORMAL; 380 + } 381 + 382 + static int mt6363_buck_unlock(struct regmap *map, bool unlock) 383 + { 384 + u16 buf = unlock ? MT6363_BUCK_TOP_UNLOCK_VALUE : 0; 385 + 386 + return regmap_bulk_write(map, MT6363_BUCK_TOP_KEY_PROT_LO, &buf, sizeof(buf)); 387 + } 388 + 389 + static int mt6363_regulator_set_mode(struct regulator_dev *rdev, 390 + unsigned int mode) 391 + { 392 + struct mt6363_regulator_info *info = rdev_get_drvdata(rdev); 393 + struct regmap *regmap = rdev->regmap; 394 + int cur_mode, ret; 395 + 396 + if (!info->modeset_reg && mode == REGULATOR_MODE_FAST) 397 + return -EOPNOTSUPP; 398 + 399 + switch (mode) { 400 + case REGULATOR_MODE_FAST: 401 + ret = mt6363_buck_unlock(regmap, true); 402 + if (ret) 403 + break; 404 + 405 + ret = regmap_set_bits(regmap, info->modeset_reg, info->modeset_mask); 406 + 407 + mt6363_buck_unlock(regmap, false); 408 + break; 409 + case REGULATOR_MODE_NORMAL: 410 + cur_mode = mt6363_regulator_get_mode(rdev); 411 + if (cur_mode < 0) { 412 + ret = cur_mode; 413 + break; 414 + } 415 + 416 + if (cur_mode == REGULATOR_MODE_FAST) { 417 + ret = mt6363_buck_unlock(regmap, true); 418 + if (ret) 419 + break; 420 + 421 + ret = regmap_clear_bits(regmap, info->modeset_reg, info->modeset_mask); 422 + 423 + mt6363_buck_unlock(regmap, false); 424 + break; 425 + } else if (cur_mode == REGULATOR_MODE_IDLE) { 426 + ret = regmap_clear_bits(regmap, info->lp_mode_reg, info->lp_mode_mask); 427 + if (ret == 0) 428 + usleep_range(100, 200); 429 + } else { 430 + ret = 0; 431 + } 432 + break; 433 + case REGULATOR_MODE_IDLE: 434 + ret = regmap_set_bits(regmap, info->lp_mode_reg, info->lp_mode_mask); 435 + break; 436 + default: 437 + ret = -EINVAL; 438 + } 439 + 440 + if (ret) { 441 + dev_err(&rdev->dev, "Failed to set mode %u: %d\n", mode, ret); 442 + return ret; 443 + } 444 + 445 + return 0; 446 + } 447 + 448 + static int mt6363_regulator_set_load(struct regulator_dev *rdev, int load_uA) 449 + { 450 + struct mt6363_regulator_info *info = rdev_get_drvdata(rdev); 451 + unsigned int opmode_cfg, opmode_en; 452 + int i, ret; 453 + 454 + if (!info->lp_imax_uA) 455 + return -EINVAL; 456 + 457 + if (load_uA >= info->lp_imax_uA) { 458 + ret = mt6363_regulator_set_mode(rdev, REGULATOR_MODE_NORMAL); 459 + if (ret) 460 + return ret; 461 + 462 + opmode_cfg = NORMAL_OP_CFG; 463 + opmode_en = NORMAL_OP_EN; 464 + } else { 465 + opmode_cfg = info->orig_op_cfg; 466 + opmode_en = info->orig_op_en; 467 + } 468 + 469 + ret = regmap_write(rdev->regmap, info->op_en_reg + OP_CFG_OFFSET, opmode_cfg); 470 + if (ret) 471 + return ret; 472 + 473 + for (i = 0; i < 3; i++) { 474 + ret = regmap_write(rdev->regmap, info->op_en_reg + i, 475 + (opmode_en >> (i * 8)) & GENMASK(7, 0)); 476 + if (ret) 477 + return ret; 478 + } 479 + 480 + return 0; 481 + } 482 + 483 + static int mt6363_vemc_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel) 484 + { 485 + const u16 tma_unlock_key = MT6363_TMA_UNLOCK_VALUE; 486 + const struct regulator_desc *rdesc = rdev->desc; 487 + struct regmap *regmap = rdev->regmap; 488 + unsigned int range, val; 489 + int i, ret; 490 + u16 mask; 491 + 492 + for (i = 0; i < rdesc->n_linear_ranges; i++) { 493 + const struct linear_range *r = &rdesc->linear_ranges[i]; 494 + unsigned int voltages_in_range = linear_range_values_in_range(r); 495 + 496 + if (sel < voltages_in_range) 497 + break; 498 + sel -= voltages_in_range; 499 + } 500 + 501 + if (i == rdesc->n_linear_ranges) 502 + return -EINVAL; 503 + 504 + ret = regmap_read(rdev->regmap, MT6363_TOP_TRAP, &val); 505 + if (ret) 506 + return ret; 507 + 508 + if (val > 1) 509 + return -EINVAL; 510 + 511 + /* Unlock TMA for writing */ 512 + ret = regmap_bulk_write(rdev->regmap, MT6363_TOP_TMA_KEY_L, 513 + &tma_unlock_key, sizeof(tma_unlock_key)); 514 + if (ret) 515 + return ret; 516 + 517 + /* If HW trapping value is 1, use VEMC_VOSEL_1 instead of VEMC_VOSEL_0 */ 518 + if (val == 1) { 519 + mask = MT6363_RG_VEMC_VOSEL_1_MASK; 520 + sel = FIELD_PREP(MT6363_RG_VEMC_VOSEL_1_MASK, sel); 521 + } else { 522 + mask = rdesc->vsel_mask; 523 + } 524 + 525 + sel <<= ffs(rdesc->vsel_mask) - 1; 526 + sel += rdesc->linear_ranges[i].min_sel; 527 + 528 + range = rdesc->linear_range_selectors_bitfield[i]; 529 + range <<= ffs(rdesc->vsel_range_mask) - 1; 530 + 531 + /* Write to the vreg calibration register for voltage finetuning */ 532 + ret = regmap_update_bits(regmap, rdesc->vsel_range_reg, 533 + rdesc->vsel_range_mask, range); 534 + if (ret) 535 + goto lock_tma; 536 + 537 + /* Function must return the result of this write operation */ 538 + ret = regmap_update_bits(regmap, rdesc->vsel_reg, mask, sel); 539 + 540 + lock_tma: 541 + /* Unconditionally re-lock TMA */ 542 + val = 0; 543 + regmap_bulk_write(rdev->regmap, MT6363_TOP_TMA_KEY_L, &val, 2); 544 + 545 + return ret; 546 + } 547 + 548 + static int mt6363_vemc_get_voltage_sel(struct regulator_dev *rdev) 549 + { 550 + const struct regulator_desc *rdesc = rdev->desc; 551 + unsigned int vosel, trap, calsel; 552 + int vcal, vsel, range, ret; 553 + 554 + ret = regmap_read(rdev->regmap, rdesc->vsel_reg, &vosel); 555 + if (ret) 556 + return ret; 557 + 558 + ret = regmap_read(rdev->regmap, rdesc->vsel_range_reg, &calsel); 559 + if (ret) 560 + return ret; 561 + 562 + calsel &= rdesc->vsel_range_mask; 563 + for (range = 0; range < rdesc->n_linear_ranges; range++) 564 + if (rdesc->linear_range_selectors_bitfield[range] != calsel) 565 + break; 566 + 567 + if (range == rdesc->n_linear_ranges) 568 + return -EINVAL; 569 + 570 + ret = regmap_read(rdev->regmap, MT6363_TOP_TRAP, &trap); 571 + if (ret) 572 + return ret; 573 + 574 + /* If HW trapping value is 1, use VEMC_VOSEL_1 instead of VEMC_VOSEL_0 */ 575 + if (trap > 1) 576 + return -EINVAL; 577 + else if (trap == 1) 578 + vsel = FIELD_GET(MT6363_RG_VEMC_VOSEL_1_MASK, vosel); 579 + else 580 + vsel = vosel & rdesc->vsel_mask; 581 + 582 + vcal = linear_range_values_in_range_array(rdesc->linear_ranges, range); 583 + 584 + return vsel + vcal; 585 + } 586 + 587 + static int mt6363_va15_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel) 588 + { 589 + struct regmap *regmap = rdev->regmap; 590 + int ret; 591 + 592 + ret = mt6363_buck_unlock(regmap, true); 593 + if (ret) 594 + return ret; 595 + 596 + ret = regulator_set_voltage_sel_pickable_regmap(rdev, sel); 597 + if (ret) 598 + goto va15_unlock; 599 + 600 + ret = regmap_update_bits(regmap, MT6363_RG_BUCK_EFUSE_RSV1, 601 + MT6363_RG_BUCK_EFUSE_RSV1_MASK, sel); 602 + if (ret) 603 + goto va15_unlock; 604 + 605 + va15_unlock: 606 + mt6363_buck_unlock(rdev->regmap, false); 607 + return ret; 608 + } 609 + 610 + static void mt6363_oc_irq_enable_work(struct work_struct *work) 611 + { 612 + struct delayed_work *dwork = to_delayed_work(work); 613 + struct mt6363_regulator_info *info = 614 + container_of(dwork, struct mt6363_regulator_info, oc_work); 615 + 616 + enable_irq(info->virq); 617 + } 618 + 619 + static irqreturn_t mt6363_oc_isr(int irq, void *data) 620 + { 621 + struct regulator_dev *rdev = (struct regulator_dev *)data; 622 + struct mt6363_regulator_info *info = rdev_get_drvdata(rdev); 623 + 624 + disable_irq_nosync(info->virq); 625 + 626 + if (regulator_is_enabled_regmap(rdev)) 627 + regulator_notifier_call_chain(rdev, REGULATOR_EVENT_OVER_CURRENT, NULL); 628 + 629 + schedule_delayed_work(&info->oc_work, msecs_to_jiffies(OC_IRQ_ENABLE_DELAY_MS)); 630 + 631 + return IRQ_HANDLED; 632 + } 633 + 634 + static int mt6363_set_ocp(struct regulator_dev *rdev, int lim, int severity, bool enable) 635 + { 636 + struct mt6363_regulator_info *info = rdev_get_drvdata(rdev); 637 + 638 + /* MT6363 supports only enabling protection and does not support limits */ 639 + if (lim || severity != REGULATOR_SEVERITY_PROT || !enable) 640 + return -EOPNOTSUPP; 641 + 642 + /* If there is no OCP interrupt, there's nothing to set */ 643 + if (info->virq <= 0) 644 + return -EOPNOTSUPP; 645 + 646 + return devm_request_threaded_irq(&rdev->dev, info->virq, NULL, 647 + mt6363_oc_isr, IRQF_ONESHOT, 648 + info->desc.name, rdev); 649 + } 650 + 651 + static const struct regulator_ops mt6363_vreg_setclr_ops = { 652 + .list_voltage = regulator_list_voltage_linear, 653 + .map_voltage = regulator_map_voltage_linear, 654 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 655 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 656 + .set_voltage_time_sel = regulator_set_voltage_time_sel, 657 + .enable = mt6363_vreg_enable_setclr, 658 + .disable = mt6363_vreg_disable_setclr, 659 + .is_enabled = regulator_is_enabled_regmap, 660 + .set_mode = mt6363_regulator_set_mode, 661 + .get_mode = mt6363_regulator_get_mode, 662 + .set_load = mt6363_regulator_set_load, 663 + .set_over_current_protection = mt6363_set_ocp, 664 + }; 665 + 666 + static const struct regulator_ops mt6363_ldo_linear_ops = { 667 + .list_voltage = regulator_list_voltage_linear, 668 + .map_voltage = regulator_map_voltage_linear, 669 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 670 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 671 + .set_voltage_time_sel = regulator_set_voltage_time_sel, 672 + .enable = regulator_enable_regmap, 673 + .disable = regulator_disable_regmap, 674 + .is_enabled = regulator_is_enabled_regmap, 675 + .set_mode = mt6363_regulator_set_mode, 676 + .get_mode = mt6363_regulator_get_mode, 677 + .set_over_current_protection = mt6363_set_ocp, 678 + }; 679 + 680 + static const struct regulator_ops mt6363_ldo_vtable_ops = { 681 + .list_voltage = regulator_list_voltage_pickable_linear_range, 682 + .map_voltage = regulator_map_voltage_pickable_linear_range, 683 + .set_voltage_sel = regulator_set_voltage_sel_pickable_regmap, 684 + .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap, 685 + .set_voltage_time_sel = regulator_set_voltage_time_sel, 686 + .enable = regulator_enable_regmap, 687 + .disable = regulator_disable_regmap, 688 + .is_enabled = regulator_is_enabled_regmap, 689 + .set_mode = mt6363_regulator_set_mode, 690 + .get_mode = mt6363_regulator_get_mode, 691 + .set_load = mt6363_regulator_set_load, 692 + .set_over_current_protection = mt6363_set_ocp, 693 + }; 694 + 695 + static const struct regulator_ops mt6363_ldo_vemc_ops = { 696 + .list_voltage = regulator_list_voltage_pickable_linear_range, 697 + .map_voltage = regulator_map_voltage_pickable_linear_range, 698 + .set_voltage_sel = mt6363_vemc_set_voltage_sel, 699 + .get_voltage_sel = mt6363_vemc_get_voltage_sel, 700 + .set_voltage_time_sel = regulator_set_voltage_time_sel, 701 + .enable = regulator_enable_regmap, 702 + .disable = regulator_disable_regmap, 703 + .is_enabled = regulator_is_enabled_regmap, 704 + .set_mode = mt6363_regulator_set_mode, 705 + .get_mode = mt6363_regulator_get_mode, 706 + .set_load = mt6363_regulator_set_load, 707 + .set_over_current_protection = mt6363_set_ocp, 708 + }; 709 + 710 + static const struct regulator_ops mt6363_ldo_va15_ops = { 711 + .list_voltage = regulator_list_voltage_pickable_linear_range, 712 + .map_voltage = regulator_map_voltage_pickable_linear_range, 713 + .set_voltage_sel = mt6363_va15_set_voltage_sel, 714 + .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap, 715 + .set_voltage_time_sel = regulator_set_voltage_time_sel, 716 + .enable = regulator_enable_regmap, 717 + .disable = regulator_disable_regmap, 718 + .is_enabled = regulator_is_enabled_regmap, 719 + .set_mode = mt6363_regulator_set_mode, 720 + .get_mode = mt6363_regulator_get_mode, 721 + .set_load = mt6363_regulator_set_load, 722 + .set_over_current_protection = mt6363_set_ocp, 723 + }; 724 + 725 + /* The array is indexed by id(MT6363_ID_XXX) */ 726 + static struct mt6363_regulator_info mt6363_regulators[] = { 727 + MT6363_BUCK("vbuck1", VBUCK1, 0, 1193750, 6250, MT6363_RG_BUCK0_EN_ADDR, 728 + MT6363_RG_BUCK0_LP_ADDR, MT6363_RG_BUCK0_FCCM_ADDR, 1), 729 + MT6363_BUCK("vbuck2", VBUCK2, 0, 1193750, 6250, MT6363_RG_BUCK0_EN_ADDR, 730 + MT6363_RG_BUCK0_LP_ADDR, MT6363_RG_BUCK0_FCCM_ADDR, 2), 731 + MT6363_BUCK("vbuck3", VBUCK3, 0, 1193750, 6250, MT6363_RG_BUCK0_EN_ADDR, 732 + MT6363_RG_BUCK0_LP_ADDR, MT6363_RG_BUCK0_FCCM_ADDR, 3), 733 + MT6363_BUCK("vbuck4", VBUCK4, 0, 1193750, 6250, MT6363_RG_BUCK0_EN_ADDR, 734 + MT6363_RG_BUCK0_LP_ADDR, MT6363_RG_BUCK0_1_FCCM_ADDR, 4), 735 + MT6363_BUCK("vbuck5", VBUCK5, 0, 1193750, 6250, MT6363_RG_BUCK0_EN_ADDR, 736 + MT6363_RG_BUCK0_LP_ADDR, MT6363_RG_BUCK0_1_FCCM_ADDR, 5), 737 + MT6363_BUCK("vbuck6", VBUCK6, 0, 1193750, 6250, MT6363_RG_BUCK0_EN_ADDR, 738 + MT6363_RG_BUCK0_LP_ADDR, MT6363_RG_BUCK0_1_FCCM_ADDR, 6), 739 + MT6363_BUCK("vbuck7", VBUCK7, 0, 1193750, 6250, MT6363_RG_BUCK0_EN_ADDR, 740 + MT6363_RG_BUCK0_LP_ADDR, MT6363_RG_BUCK0_1_FCCM_ADDR, 7), 741 + MT6363_BUCK("vs1", VS1, 0, 2200000, 12500, MT6363_RG_BUCK1_EN_ADDR, 742 + MT6363_RG_BUCK1_LP_ADDR, MT6363_RG_VS1_FCCM_ADDR, 8), 743 + MT6363_BUCK("vs2", VS2, 0, 1600000, 12500, MT6363_RG_BUCK0_EN_ADDR, 744 + MT6363_RG_BUCK0_LP_ADDR, MT6363_RG_BUCK0_FCCM_ADDR, 0), 745 + MT6363_BUCK("vs3", VS3, 0, 1193750, 6250, MT6363_RG_BUCK1_EN_ADDR, 746 + MT6363_RG_BUCK1_LP_ADDR, MT6363_RG_VS3_FCCM_ADDR, 9), 747 + MT6363_LDO_VT("va12-1", VA12_1, "vs2-ldo2", 3, 37), 748 + MT6363_LDO_VT("va12-2", VA12_2, "vs2-ldo2", 3, 38), 749 + MT6363_LDO_LINEAR_CAL_OPS("va15", VA15, "vs1-ldo1", mt6363_ldo_va15_ops, 3, 39), 750 + MT6363_LDO_VT("vaux18", VAUX18, "vsys-ldo1", 2, 31), 751 + MT6363_LDO_VT("vcn13", VCN13, "vs2-ldo2", 1, 17), 752 + MT6363_LDO_VT("vcn15", VCN15, "vs1-ldo2", 3, 16), 753 + MT6363_LDO_LINEAR_CAL_OPS("vemc", VEMC, "vsys-ldo1", mt6363_ldo_vemc_ops, 0, 32), 754 + MT6363_LDO_VT("vio0p75", VIO075, "vs1-ldo1", 5, 36), 755 + MT6363_LDO_VT("vio18", VIO18, "vs1-ldo2", 3, 35), 756 + MT6363_LDO_VT("vm18", VM18, "vs1-ldo1", 4, 40), 757 + MT6363_LDO_L("vsram-apu", VSRAM_APU, "vs3-ldo1", 400000, 1193750, 6250, BUCK1, 30), 758 + MT6363_LDO_L("vsram-cpub", VSRAM_CPUB, "vs2-ldo1", 400000, 1193750, 6250, BUCK1, 27), 759 + MT6363_LDO_L("vsram-cpum", VSRAM_CPUM, "vs2-ldo1", 400000, 1193750, 6250, BUCK1, 28), 760 + MT6363_LDO_L("vsram-cpul", VSRAM_CPUL, "vs2-ldo2", 400000, 1193750, 6250, BUCK1, 29), 761 + MT6363_LDO_L_SC("vsram-digrf", VSRAM_DIGRF, "vs3-ldo1", 400000, 1193750, 6250, BUCK1, 23), 762 + MT6363_LDO_L_SC("vsram-mdfe", VSRAM_MDFE, "vs3-ldo1", 400000, 1193750, 6250, BUCK1, 24), 763 + MT6363_LDO_L_SC("vsram-modem", VSRAM_MODEM, "vs3-ldo2", 400000, 1193750, 6250, BUCK1, 25), 764 + MT6363_LDO_VT("vrf0p9", VRF09, "vs3-ldo2", 1, 18), 765 + MT6363_LDO_VT("vrf12", VRF12, "vs2-ldo1", 3, 19), 766 + MT6363_LDO_VT("vrf13", VRF13, "vs2-ldo1", 1, 20), 767 + MT6363_LDO_VT("vrf18", VRF18, "vs1-ldo1", 3, 21), 768 + MT6363_LDO_VT("vrf-io18", VRFIO18, "vs1-ldo1", 3, 22), 769 + MT6363_LDO_VT("vtref18", VTREF18, "vsys-ldo1", 2, 26), 770 + MT6363_LDO_VT("vufs12", VUFS12, "vs2-ldo1", 4, 33), 771 + MT6363_LDO_VT("vufs18", VUFS18, "vs1-ldo2", 3, 34), 772 + }; 773 + 774 + static int mt6363_backup_op_setting(struct regmap *map, struct mt6363_regulator_info *info) 775 + { 776 + unsigned int i, val; 777 + int ret; 778 + 779 + ret = regmap_read(map, info->op_en_reg + OP_CFG_OFFSET, &val); 780 + if (ret) 781 + return ret; 782 + 783 + info->orig_op_cfg = val; 784 + 785 + for (i = 0; i < 3; i++) { 786 + ret = regmap_read(map, info->op_en_reg + i, &val); 787 + if (ret) 788 + return ret; 789 + 790 + info->orig_op_en |= val << (i * 8); 791 + } 792 + 793 + return 0; 794 + } 795 + 796 + static void mt6363_irq_remove(void *data) 797 + { 798 + int *virq = data; 799 + 800 + irq_dispose_mapping(*virq); 801 + } 802 + 803 + static void mt6363_spmi_remove(void *data) 804 + { 805 + struct spmi_device *sdev = data; 806 + 807 + spmi_device_remove(sdev); 808 + }; 809 + 810 + static struct regmap *mt6363_spmi_register_regmap(struct device *dev) 811 + { 812 + struct regmap_config mt6363_regmap_config = { 813 + .reg_bits = 16, 814 + .val_bits = 16, 815 + .max_register = 0x1f90, 816 + .fast_io = true, 817 + }; 818 + struct spmi_device *sdev, *sparent; 819 + u32 base; 820 + int ret; 821 + 822 + if (!dev->parent) 823 + return ERR_PTR(-ENODEV); 824 + 825 + ret = device_property_read_u32(dev, "reg", &base); 826 + if (ret) 827 + return ERR_PTR(ret); 828 + 829 + sparent = to_spmi_device(dev->parent); 830 + if (!sparent) 831 + return ERR_PTR(-ENODEV); 832 + 833 + sdev = spmi_device_alloc(sparent->ctrl); 834 + if (!sdev) 835 + return ERR_PTR(-ENODEV); 836 + 837 + sdev->usid = sparent->usid; 838 + dev_set_name(&sdev->dev, "%d-%02x-regulator", sdev->ctrl->nr, sdev->usid); 839 + ret = device_add(&sdev->dev); 840 + if (ret) { 841 + put_device(&sdev->dev); 842 + return ERR_PTR(ret); 843 + }; 844 + 845 + ret = devm_add_action_or_reset(dev, mt6363_spmi_remove, sdev); 846 + if (ret) 847 + return ERR_PTR(ret); 848 + 849 + mt6363_regmap_config.reg_base = base; 850 + 851 + return devm_regmap_init_spmi_ext(sdev, &mt6363_regmap_config); 852 + } 853 + 854 + static int mt6363_regulator_probe(struct platform_device *pdev) 855 + { 856 + struct device_node *interrupt_parent; 857 + struct regulator_config config = {}; 858 + struct mt6363_regulator_info *info; 859 + struct device *dev = &pdev->dev; 860 + struct regulator_dev *rdev; 861 + struct irq_domain *domain; 862 + struct irq_fwspec fwspec; 863 + struct spmi_device *sdev; 864 + int i, ret; 865 + 866 + config.regmap = mt6363_spmi_register_regmap(dev); 867 + if (IS_ERR(config.regmap)) 868 + return dev_err_probe(dev, PTR_ERR(config.regmap), 869 + "Cannot get regmap\n"); 870 + config.dev = dev; 871 + sdev = to_spmi_device(dev->parent); 872 + 873 + interrupt_parent = of_irq_find_parent(dev->of_node); 874 + if (!interrupt_parent) 875 + return dev_err_probe(dev, -EINVAL, "Cannot find IRQ parent\n"); 876 + 877 + domain = irq_find_host(interrupt_parent); 878 + of_node_put(interrupt_parent); 879 + fwspec.fwnode = domain->fwnode; 880 + 881 + fwspec.param_count = 3; 882 + fwspec.param[0] = sdev->usid; 883 + fwspec.param[2] = IRQ_TYPE_LEVEL_HIGH; 884 + 885 + for (i = 0; i < ARRAY_SIZE(mt6363_regulators); i++) { 886 + info = &mt6363_regulators[i]; 887 + 888 + fwspec.param[1] = info->hwirq; 889 + info->virq = irq_create_fwspec_mapping(&fwspec); 890 + if (!info->virq) 891 + return dev_err_probe(dev, -EINVAL, 892 + "Failed to map IRQ%d\n", info->hwirq); 893 + 894 + ret = devm_add_action_or_reset(dev, mt6363_irq_remove, &info->virq); 895 + if (ret) { 896 + irq_dispose_mapping(info->hwirq); 897 + return ret; 898 + } 899 + 900 + config.driver_data = info; 901 + INIT_DELAYED_WORK(&info->oc_work, mt6363_oc_irq_enable_work); 902 + 903 + rdev = devm_regulator_register(dev, &info->desc, &config); 904 + if (IS_ERR(rdev)) 905 + return dev_err_probe(dev, PTR_ERR(rdev), 906 + "failed to register %s\n", info->desc.name); 907 + 908 + if (info->lp_imax_uA) { 909 + ret = mt6363_backup_op_setting(config.regmap, info); 910 + if (ret) { 911 + dev_warn(dev, "Failed to backup op_setting for %s\n", 912 + info->desc.name); 913 + info->lp_imax_uA = 0; 914 + } 915 + } 916 + } 917 + 918 + return 0; 919 + } 920 + 921 + static const struct of_device_id mt6363_regulator_match[] = { 922 + { .compatible = "mediatek,mt6363-regulator" }, 923 + { /* sentinel */ } 924 + }; 925 + 926 + static struct platform_driver mt6363_regulator_driver = { 927 + .driver = { 928 + .name = "mt6363-regulator", 929 + .probe_type = PROBE_PREFER_ASYNCHRONOUS, 930 + .of_match_table = mt6363_regulator_match, 931 + }, 932 + .probe = mt6363_regulator_probe, 933 + }; 934 + module_platform_driver(mt6363_regulator_driver); 935 + 936 + MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>"); 937 + MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6363 PMIC"); 938 + MODULE_LICENSE("GPL");
+330
include/linux/regulator/mt6363-regulator.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2024 MediaTek Inc. 4 + * Copyright (c) 2025 Collabora Ltd 5 + */ 6 + 7 + #include <linux/bits.h> 8 + 9 + #ifndef __LINUX_REGULATOR_MT6363_H 10 + #define __LINUX_REGULATOR_MT6363_H 11 + 12 + /* Register */ 13 + #define MT6363_TOP_TRAP 0x6 14 + #define MT6363_TOP_TMA_KEY_L 0x36e 15 + #define MT6363_RG_BUCK0_EN_ADDR 0x210 16 + #define MT6363_RG_BUCK_VS2_EN_BIT 0 17 + #define MT6363_RG_BUCK_VBUCK1_EN_BIT 1 18 + #define MT6363_RG_BUCK_VBUCK2_EN_BIT 2 19 + #define MT6363_RG_BUCK_VBUCK3_EN_BIT 3 20 + #define MT6363_RG_BUCK_VBUCK4_EN_BIT 4 21 + #define MT6363_RG_BUCK_VBUCK5_EN_BIT 5 22 + #define MT6363_RG_BUCK_VBUCK6_EN_BIT 6 23 + #define MT6363_RG_BUCK_VBUCK7_EN_BIT 7 24 + #define MT6363_RG_BUCK1_EN_ADDR 0x213 25 + #define MT6363_RG_BUCK_VS1_EN_BIT 0 26 + #define MT6363_RG_BUCK_VS3_EN_BIT 1 27 + #define MT6363_RG_LDO_VSRAM_DIGRF_EN_BIT 4 28 + #define MT6363_RG_LDO_VSRAM_MDFE_EN_BIT 5 29 + #define MT6363_RG_LDO_VSRAM_MODEM_EN_BIT 6 30 + #define MT6363_RG_BUCK0_LP_ADDR 0x216 31 + #define MT6363_RG_BUCK_VS2_LP_BIT 0 32 + #define MT6363_RG_BUCK_VBUCK1_LP_BIT 1 33 + #define MT6363_RG_BUCK_VBUCK2_LP_BIT 2 34 + #define MT6363_RG_BUCK_VBUCK3_LP_BIT 3 35 + #define MT6363_RG_BUCK_VBUCK4_LP_BIT 4 36 + #define MT6363_RG_BUCK_VBUCK5_LP_BIT 5 37 + #define MT6363_RG_BUCK_VBUCK6_LP_BIT 6 38 + #define MT6363_RG_BUCK_VBUCK7_LP_BIT 7 39 + #define MT6363_RG_BUCK1_LP_ADDR 0x219 40 + #define MT6363_RG_BUCK_VS1_LP_BIT 0 41 + #define MT6363_RG_BUCK_VS3_LP_BIT 1 42 + #define MT6363_RG_LDO_VSRAM_DIGRF_LP_BIT 4 43 + #define MT6363_RG_LDO_VSRAM_MDFE_LP_BIT 5 44 + #define MT6363_RG_LDO_VSRAM_MODEM_LP_BIT 6 45 + #define MT6363_RG_BUCK_VS2_VOSEL_ADDR 0x21c 46 + #define MT6363_RG_BUCK_VS2_VOSEL_MASK GENMASK(7, 0) 47 + #define MT6363_RG_BUCK_VBUCK1_VOSEL_ADDR 0x21d 48 + #define MT6363_RG_BUCK_VBUCK1_VOSEL_MASK GENMASK(7, 0) 49 + #define MT6363_RG_BUCK_VBUCK2_VOSEL_ADDR 0x21e 50 + #define MT6363_RG_BUCK_VBUCK2_VOSEL_MASK GENMASK(7, 0) 51 + #define MT6363_RG_BUCK_VBUCK3_VOSEL_ADDR 0x21f 52 + #define MT6363_RG_BUCK_VBUCK3_VOSEL_MASK GENMASK(7, 0) 53 + #define MT6363_RG_BUCK_VBUCK4_VOSEL_ADDR 0x220 54 + #define MT6363_RG_BUCK_VBUCK4_VOSEL_MASK GENMASK(7, 0) 55 + #define MT6363_RG_BUCK_VBUCK5_VOSEL_ADDR 0x221 56 + #define MT6363_RG_BUCK_VBUCK5_VOSEL_MASK GENMASK(7, 0) 57 + #define MT6363_RG_BUCK_VBUCK6_VOSEL_ADDR 0x222 58 + #define MT6363_RG_BUCK_VBUCK6_VOSEL_MASK GENMASK(7, 0) 59 + #define MT6363_RG_BUCK_VBUCK7_VOSEL_ADDR 0x223 60 + #define MT6363_RG_BUCK_VBUCK7_VOSEL_MASK GENMASK(7, 0) 61 + #define MT6363_RG_BUCK_VS1_VOSEL_ADDR 0x224 62 + #define MT6363_RG_BUCK_VS1_VOSEL_MASK GENMASK(7, 0) 63 + #define MT6363_RG_BUCK_VS3_VOSEL_ADDR 0x225 64 + #define MT6363_RG_BUCK_VS3_VOSEL_MASK GENMASK(7, 0) 65 + #define MT6363_RG_LDO_VSRAM_DIGRF_VOSEL_ADDR 0x228 66 + #define MT6363_RG_LDO_VSRAM_DIGRF_VOSEL_MASK GENMASK(6, 0) 67 + #define MT6363_RG_LDO_VSRAM_MDFE_VOSEL_ADDR 0x229 68 + #define MT6363_RG_LDO_VSRAM_MDFE_VOSEL_MASK GENMASK(6, 0) 69 + #define MT6363_RG_LDO_VSRAM_MODEM_VOSEL_ADDR 0x22a 70 + #define MT6363_RG_LDO_VSRAM_MODEM_VOSEL_MASK GENMASK(6, 0) 71 + #define MT6363_BUCK_TOP_KEY_PROT_LO 0x13fa 72 + #define MT6363_BUCK_VS2_WDTDBG_VOSEL_ADDR 0x13fc 73 + #define MT6363_BUCK_VBUCK1_WDTDBG_VOSEL_ADDR 0x13fd 74 + #define MT6363_BUCK_VBUCK2_WDTDBG_VOSEL_ADDR 0x13fe 75 + #define MT6363_BUCK_VBUCK3_WDTDBG_VOSEL_ADDR 0x13ff 76 + #define MT6363_BUCK_VBUCK4_WDTDBG_VOSEL_ADDR 0x1400 77 + #define MT6363_BUCK_VBUCK5_WDTDBG_VOSEL_ADDR 0x1401 78 + #define MT6363_BUCK_VBUCK6_WDTDBG_VOSEL_ADDR 0x1402 79 + #define MT6363_BUCK_VBUCK7_WDTDBG_VOSEL_ADDR 0x1403 80 + #define MT6363_BUCK_VS1_WDTDBG_VOSEL_ADDR 0x1404 81 + #define MT6363_BUCK_VS3_WDTDBG_VOSEL_ADDR 0x1405 82 + #define MT6363_RG_BUCK_EFUSE_RSV1 0x1417 83 + #define MT6363_RG_BUCK_EFUSE_RSV1_MASK GENMASK(7, 4) 84 + #define MT6363_BUCK_VS2_OP_EN_0 0x145d 85 + #define MT6363_BUCK_VS2_HW_LP_MODE 0x1468 86 + #define MT6363_BUCK_VBUCK1_OP_EN_0 0x14dd 87 + #define MT6363_BUCK_VBUCK1_HW_LP_MODE 0x14e8 88 + #define MT6363_RG_BUCK_VBUCK1_SSHUB_EN_ADDR 0x14ea 89 + #define MT6363_RG_BUCK_VBUCK1_SSHUB_VOSEL_ADDR 0x14eb 90 + #define MT6363_RG_BUCK_VBUCK1_SSHUB_VOSEL_MASK GENMASK(7, 0) 91 + #define MT6363_BUCK_VBUCK2_OP_EN_0 0x155d 92 + #define MT6363_BUCK_VBUCK2_HW_LP_MODE 0x1568 93 + #define MT6363_RG_BUCK_VBUCK2_SSHUB_EN_ADDR 0x156a 94 + #define MT6363_RG_BUCK_VBUCK2_SSHUB_VOSEL_ADDR 0x156b 95 + #define MT6363_RG_BUCK_VBUCK2_SSHUB_VOSEL_MASK GENMASK(7, 0) 96 + #define MT6363_BUCK_VBUCK3_OP_EN_0 0x15dd 97 + #define MT6363_BUCK_VBUCK3_HW_LP_MODE 0x15e8 98 + #define MT6363_BUCK_VBUCK4_OP_EN_0 0x165d 99 + #define MT6363_BUCK_VBUCK4_HW_LP_MODE 0x1668 100 + #define MT6363_RG_BUCK_VBUCK4_SSHUB_EN_ADDR 0x166a 101 + #define MT6363_RG_BUCK_VBUCK4_SSHUB_VOSEL_ADDR 0x166b 102 + #define MT6363_RG_BUCK_VBUCK4_SSHUB_VOSEL_MASK GENMASK(7, 0) 103 + #define MT6363_BUCK_VBUCK5_OP_EN_0 0x16dd 104 + #define MT6363_BUCK_VBUCK5_HW_LP_MODE 0x16e8 105 + #define MT6363_BUCK_VBUCK6_OP_EN_0 0x175d 106 + #define MT6363_BUCK_VBUCK6_HW_LP_MODE 0x1768 107 + #define MT6363_BUCK_VBUCK7_OP_EN_0 0x17dd 108 + #define MT6363_BUCK_VBUCK7_HW_LP_MODE 0x17e8 109 + #define MT6363_BUCK_VS1_OP_EN_0 0x185d 110 + #define MT6363_BUCK_VS1_HW_LP_MODE 0x1868 111 + #define MT6363_BUCK_VS3_OP_EN_0 0x18dd 112 + #define MT6363_BUCK_VS3_HW_LP_MODE 0x18e8 113 + #define MT6363_RG_VS1_FCCM_ADDR 0x1964 114 + #define MT6363_RG_VS1_FCCM_BIT 0 115 + #define MT6363_RG_VS3_FCCM_ADDR 0x1973 116 + #define MT6363_RG_VS3_FCCM_BIT 0 117 + #define MT6363_RG_BUCK0_FCCM_ADDR 0x1a02 118 + #define MT6363_RG_VBUCK1_FCCM_BIT 0 119 + #define MT6363_RG_VBUCK2_FCCM_BIT 1 120 + #define MT6363_RG_VBUCK3_FCCM_BIT 2 121 + #define MT6363_RG_VS2_FCCM_BIT 3 122 + #define MT6363_RG_BUCK0_1_FCCM_ADDR 0x1a82 123 + #define MT6363_RG_VBUCK4_FCCM_BIT 0 124 + #define MT6363_RG_VBUCK5_FCCM_BIT 1 125 + #define MT6363_RG_VBUCK6_FCCM_BIT 2 126 + #define MT6363_RG_VBUCK7_FCCM_BIT 3 127 + #define MT6363_RG_VCN13_VOSEL_ADDR 0x1b0f 128 + #define MT6363_RG_VCN13_VOSEL_MASK GENMASK(3, 0) 129 + #define MT6363_RG_VEMC_VOSEL_ADDR 0x1b10 130 + #define MT6363_RG_VEMC_VOSEL_MASK GENMASK(3, 0) 131 + #define MT6363_RG_VEMC_VOSEL_1_MASK GENMASK(7, 4) 132 + #define MT6363_RG_LDO_VSRAM_CPUB_VOSEL_ADDR 0x1b14 133 + #define MT6363_RG_LDO_VSRAM_CPUB_VOSEL_MASK GENMASK(6, 0) 134 + #define MT6363_RG_LDO_VSRAM_CPUM_VOSEL_ADDR 0x1b15 135 + #define MT6363_RG_LDO_VSRAM_CPUM_VOSEL_MASK GENMASK(6, 0) 136 + #define MT6363_RG_LDO_VSRAM_CPUL_VOSEL_ADDR 0x1b16 137 + #define MT6363_RG_LDO_VSRAM_CPUL_VOSEL_MASK GENMASK(6, 0) 138 + #define MT6363_RG_LDO_VSRAM_APU_VOSEL_ADDR 0x1b17 139 + #define MT6363_RG_LDO_VSRAM_APU_VOSEL_MASK GENMASK(6, 0) 140 + #define MT6363_RG_VEMC_VOCAL_ADDR 0x1b1b 141 + #define MT6363_RG_VEMC_VOCAL_MASK GENMASK(3, 0) 142 + #define MT6363_RG_LDO_VCN15_ADDR 0x1b57 143 + #define MT6363_RG_LDO_VCN15_EN_BIT 0 144 + #define MT6363_RG_LDO_VCN15_LP_BIT 1 145 + #define MT6363_LDO_VCN15_HW_LP_MODE 0x1b5b 146 + #define MT6363_LDO_VCN15_OP_EN0 0x1b5c 147 + #define MT6363_RG_LDO_VRF09_ADDR 0x1b65 148 + #define MT6363_RG_LDO_VRF09_EN_BIT 0 149 + #define MT6363_RG_LDO_VRF09_LP_BIT 1 150 + #define MT6363_LDO_VRF09_HW_LP_MODE 0x1b69 151 + #define MT6363_LDO_VRF09_OP_EN0 0x1b6a 152 + #define MT6363_RG_LDO_VRF12_ADDR 0x1b73 153 + #define MT6363_RG_LDO_VRF12_EN_BIT 0 154 + #define MT6363_RG_LDO_VRF12_LP_BIT 1 155 + #define MT6363_LDO_VRF12_HW_LP_MODE 0x1b77 156 + #define MT6363_LDO_VRF12_OP_EN0 0x1b78 157 + #define MT6363_RG_LDO_VRF13_ADDR 0x1b81 158 + #define MT6363_RG_LDO_VRF13_EN_BIT 0 159 + #define MT6363_RG_LDO_VRF13_LP_BIT 1 160 + #define MT6363_LDO_VRF13_HW_LP_MODE 0x1b85 161 + #define MT6363_LDO_VRF13_OP_EN0 0x1b86 162 + #define MT6363_RG_LDO_VRF18_ADDR 0x1b8f 163 + #define MT6363_RG_LDO_VRF18_EN_BIT 0 164 + #define MT6363_RG_LDO_VRF18_LP_BIT 1 165 + #define MT6363_LDO_VRF18_HW_LP_MODE 0x1b93 166 + #define MT6363_LDO_VRF18_OP_EN0 0x1b94 167 + #define MT6363_RG_LDO_VRFIO18_ADDR 0x1b9d 168 + #define MT6363_RG_LDO_VRFIO18_EN_BIT 0 169 + #define MT6363_RG_LDO_VRFIO18_LP_BIT 1 170 + #define MT6363_LDO_VRFIO18_HW_LP_MODE 0x1ba1 171 + #define MT6363_LDO_VRFIO18_OP_EN0 0x1ba2 172 + #define MT6363_RG_LDO_VTREF18_ADDR 0x1bd7 173 + #define MT6363_RG_LDO_VTREF18_EN_BIT 0 174 + #define MT6363_RG_LDO_VTREF18_LP_BIT 1 175 + #define MT6363_LDO_VTREF18_HW_LP_MODE 0x1bdb 176 + #define MT6363_LDO_VTREF18_OP_EN0 0x1bdc 177 + #define MT6363_RG_LDO_VAUX18_ADDR 0x1be5 178 + #define MT6363_RG_LDO_VAUX18_EN_BIT 0 179 + #define MT6363_RG_LDO_VAUX18_LP_BIT 1 180 + #define MT6363_LDO_VAUX18_HW_LP_MODE 0x1be9 181 + #define MT6363_LDO_VAUX18_OP_EN0 0x1bea 182 + #define MT6363_RG_LDO_VEMC_ADDR 0x1bf3 183 + #define MT6363_RG_LDO_VEMC_EN_BIT 0 184 + #define MT6363_RG_LDO_VEMC_LP_BIT 1 185 + #define MT6363_LDO_VEMC_HW_LP_MODE 0x1bf7 186 + #define MT6363_LDO_VEMC_OP_EN0 0x1bf8 187 + #define MT6363_RG_LDO_VUFS12_ADDR 0x1c01 188 + #define MT6363_RG_LDO_VUFS12_EN_BIT 0 189 + #define MT6363_RG_LDO_VUFS12_LP_BIT 1 190 + #define MT6363_LDO_VUFS12_HW_LP_MODE 0x1c05 191 + #define MT6363_LDO_VUFS12_OP_EN0 0x1c06 192 + #define MT6363_RG_LDO_VUFS18_ADDR 0x1c0f 193 + #define MT6363_RG_LDO_VUFS18_EN_BIT 0 194 + #define MT6363_RG_LDO_VUFS18_LP_BIT 1 195 + #define MT6363_LDO_VUFS18_HW_LP_MODE 0x1c13 196 + #define MT6363_LDO_VUFS18_OP_EN0 0x1c14 197 + #define MT6363_RG_LDO_VIO18_ADDR 0x1c1d 198 + #define MT6363_RG_LDO_VIO18_EN_BIT 0 199 + #define MT6363_RG_LDO_VIO18_LP_BIT 1 200 + #define MT6363_LDO_VIO18_HW_LP_MODE 0x1c21 201 + #define MT6363_LDO_VIO18_OP_EN0 0x1c22 202 + #define MT6363_RG_LDO_VIO075_ADDR 0x1c57 203 + #define MT6363_RG_LDO_VIO075_EN_BIT 0 204 + #define MT6363_RG_LDO_VIO075_LP_BIT 1 205 + #define MT6363_LDO_VIO075_HW_LP_MODE 0x1c5b 206 + #define MT6363_LDO_VIO075_OP_EN0 0x1c5c 207 + #define MT6363_RG_LDO_VA12_1_ADDR 0x1c65 208 + #define MT6363_RG_LDO_VA12_1_EN_BIT 0 209 + #define MT6363_RG_LDO_VA12_1_LP_BIT 1 210 + #define MT6363_LDO_VA12_1_HW_LP_MODE 0x1c69 211 + #define MT6363_LDO_VA12_1_OP_EN0 0x1c6a 212 + #define MT6363_RG_LDO_VA12_2_ADDR 0x1c73 213 + #define MT6363_RG_LDO_VA12_2_EN_BIT 0 214 + #define MT6363_RG_LDO_VA12_2_LP_BIT 1 215 + #define MT6363_LDO_VA12_2_HW_LP_MODE 0x1c77 216 + #define MT6363_LDO_VA12_2_OP_EN0 0x1c78 217 + #define MT6363_RG_LDO_VA15_ADDR 0x1c81 218 + #define MT6363_RG_LDO_VA15_EN_BIT 0 219 + #define MT6363_RG_LDO_VA15_LP_BIT 1 220 + #define MT6363_LDO_VA15_HW_LP_MODE 0x1c85 221 + #define MT6363_LDO_VA15_OP_EN0 0x1c86 222 + #define MT6363_RG_LDO_VM18_ADDR 0x1c8f 223 + #define MT6363_RG_LDO_VM18_EN_BIT 0 224 + #define MT6363_RG_LDO_VM18_LP_BIT 1 225 + #define MT6363_LDO_VM18_HW_LP_MODE 0x1c93 226 + #define MT6363_LDO_VM18_OP_EN0 0x1c94 227 + #define MT6363_RG_LDO_VCN13_ADDR 0x1cd7 228 + #define MT6363_RG_LDO_VCN13_EN_BIT 0 229 + #define MT6363_RG_LDO_VCN13_LP_BIT 1 230 + #define MT6363_LDO_VCN13_HW_LP_MODE 0x1cdb 231 + #define MT6363_LDO_VCN13_OP_EN0 0x1ce4 232 + #define MT6363_LDO_VSRAM_DIGRF_HW_LP_MODE 0x1cf1 233 + #define MT6363_LDO_VSRAM_DIGRF_OP_EN0 0x1cfa 234 + #define MT6363_LDO_VSRAM_MDFE_HW_LP_MODE 0x1d5b 235 + #define MT6363_LDO_VSRAM_MDFE_OP_EN0 0x1d64 236 + #define MT6363_LDO_VSRAM_MODEM_HW_LP_MODE 0x1d76 237 + #define MT6363_LDO_VSRAM_MODEM_OP_EN0 0x1d7f 238 + #define MT6363_RG_LDO_VSRAM_CPUB_ADDR 0x1dd7 239 + #define MT6363_RG_LDO_VSRAM_CPUB_EN_BIT 0 240 + #define MT6363_RG_LDO_VSRAM_CPUB_LP_BIT 1 241 + #define MT6363_LDO_VSRAM_CPUB_HW_LP_MODE 0x1ddb 242 + #define MT6363_LDO_VSRAM_CPUB_OP_EN0 0x1de4 243 + #define MT6363_RG_LDO_VSRAM_CPUM_ADDR 0x1ded 244 + #define MT6363_RG_LDO_VSRAM_CPUM_EN_BIT 0 245 + #define MT6363_RG_LDO_VSRAM_CPUM_LP_BIT 1 246 + #define MT6363_LDO_VSRAM_CPUM_HW_LP_MODE 0x1df1 247 + #define MT6363_LDO_VSRAM_CPUM_OP_EN0 0x1dfa 248 + #define MT6363_RG_LDO_VSRAM_CPUL_ADDR 0x1e57 249 + #define MT6363_RG_LDO_VSRAM_CPUL_EN_BIT 0 250 + #define MT6363_RG_LDO_VSRAM_CPUL_LP_BIT 1 251 + #define MT6363_LDO_VSRAM_CPUL_HW_LP_MODE 0x1e5b 252 + #define MT6363_LDO_VSRAM_CPUL_OP_EN0 0x1e64 253 + #define MT6363_RG_LDO_VSRAM_APU_ADDR 0x1e6d 254 + #define MT6363_RG_LDO_VSRAM_APU_EN_BIT 0 255 + #define MT6363_RG_LDO_VSRAM_APU_LP_BIT 1 256 + #define MT6363_LDO_VSRAM_APU_HW_LP_MODE 0x1e71 257 + #define MT6363_LDO_VSRAM_APU_OP_EN0 0x1e7a 258 + #define MT6363_RG_VTREF18_VOCAL_ADDR 0x1ed8 259 + #define MT6363_RG_VTREF18_VOCAL_MASK GENMASK(3, 0) 260 + #define MT6363_RG_VTREF18_VOSEL_ADDR 0x1ed9 261 + #define MT6363_RG_VTREF18_VOSEL_MASK GENMASK(3, 0) 262 + #define MT6363_RG_VAUX18_VOCAL_ADDR 0x1edc 263 + #define MT6363_RG_VAUX18_VOCAL_MASK GENMASK(3, 0) 264 + #define MT6363_RG_VAUX18_VOSEL_ADDR 0x1edd 265 + #define MT6363_RG_VAUX18_VOSEL_MASK GENMASK(3, 0) 266 + #define MT6363_RG_VCN15_VOCAL_ADDR 0x1ee3 267 + #define MT6363_RG_VCN15_VOCAL_MASK GENMASK(3, 0) 268 + #define MT6363_RG_VCN15_VOSEL_ADDR 0x1ee4 269 + #define MT6363_RG_VCN15_VOSEL_MASK GENMASK(3, 0) 270 + #define MT6363_RG_VUFS18_VOCAL_ADDR 0x1ee7 271 + #define MT6363_RG_VUFS18_VOCAL_MASK GENMASK(3, 0) 272 + #define MT6363_RG_VUFS18_VOSEL_ADDR 0x1ee8 273 + #define MT6363_RG_VUFS18_VOSEL_MASK GENMASK(3, 0) 274 + #define MT6363_RG_VIO18_VOCAL_ADDR 0x1eeb 275 + #define MT6363_RG_VIO18_VOCAL_MASK GENMASK(3, 0) 276 + #define MT6363_RG_VIO18_VOSEL_ADDR 0x1eec 277 + #define MT6363_RG_VIO18_VOSEL_MASK GENMASK(3, 0) 278 + #define MT6363_RG_VM18_VOCAL_ADDR 0x1eef 279 + #define MT6363_RG_VM18_VOCAL_MASK GENMASK(3, 0) 280 + #define MT6363_RG_VM18_VOSEL_ADDR 0x1ef0 281 + #define MT6363_RG_VM18_VOSEL_MASK GENMASK(3, 0) 282 + #define MT6363_RG_VA15_VOCAL_ADDR 0x1ef3 283 + #define MT6363_RG_VA15_VOCAL_MASK GENMASK(3, 0) 284 + #define MT6363_RG_VA15_VOSEL_ADDR 0x1ef4 285 + #define MT6363_RG_VA15_VOSEL_MASK GENMASK(3, 0) 286 + #define MT6363_RG_VRF18_VOCAL_ADDR 0x1ef7 287 + #define MT6363_RG_VRF18_VOCAL_MASK GENMASK(3, 0) 288 + #define MT6363_RG_VRF18_VOSEL_ADDR 0x1ef8 289 + #define MT6363_RG_VRF18_VOSEL_MASK GENMASK(3, 0) 290 + #define MT6363_RG_VRFIO18_VOCAL_ADDR 0x1efb 291 + #define MT6363_RG_VRFIO18_VOCAL_MASK GENMASK(3, 0) 292 + #define MT6363_RG_VRFIO18_VOSEL_ADDR 0x1efc 293 + #define MT6363_RG_VRFIO18_VOSEL_MASK GENMASK(3, 0) 294 + #define MT6363_RG_VIO075_VOCFG_ADDR 0x1f01 295 + #define MT6363_RG_VIO075_VOCAL_ADDR MT6363_RG_VIO075_VOCFG_ADDR 296 + #define MT6363_RG_VIO075_VOCAL_MASK GENMASK(3, 0) 297 + #define MT6363_RG_VIO075_VOSEL_ADDR MT6363_RG_VIO075_VOCFG_ADDR 298 + #define MT6363_RG_VIO075_VOSEL_MASK GENMASK(6, 4) 299 + #define MT6363_RG_VCN13_VOCAL_ADDR 0x1f58 300 + #define MT6363_RG_VCN13_VOCAL_MASK GENMASK(3, 0) 301 + #define MT6363_RG_VUFS12_VOCAL_ADDR 0x1f61 302 + #define MT6363_RG_VUFS12_VOCAL_MASK GENMASK(3, 0) 303 + #define MT6363_RG_VUFS12_VOSEL_ADDR 0x1f62 304 + #define MT6363_RG_VUFS12_VOSEL_MASK GENMASK(3, 0) 305 + #define MT6363_RG_VA12_1_VOCAL_ADDR 0x1f65 306 + #define MT6363_RG_VA12_1_VOCAL_MASK GENMASK(3, 0) 307 + #define MT6363_RG_VA12_1_VOSEL_ADDR 0x1f66 308 + #define MT6363_RG_VA12_1_VOSEL_MASK GENMASK(3, 0) 309 + #define MT6363_RG_VA12_2_VOCAL_ADDR 0x1f69 310 + #define MT6363_RG_VA12_2_VOCAL_MASK GENMASK(3, 0) 311 + #define MT6363_RG_VA12_2_VOSEL_ADDR 0x1f6a 312 + #define MT6363_RG_VA12_2_VOSEL_MASK GENMASK(3, 0) 313 + #define MT6363_RG_VRF12_VOCAL_ADDR 0x1f6d 314 + #define MT6363_RG_VRF12_VOCAL_MASK GENMASK(3, 0) 315 + #define MT6363_RG_VRF12_VOSEL_ADDR 0x1f6e 316 + #define MT6363_RG_VRF12_VOSEL_MASK GENMASK(3, 0) 317 + #define MT6363_RG_VRF13_VOCAL_ADDR 0x1f71 318 + #define MT6363_RG_VRF13_VOCAL_MASK GENMASK(3, 0) 319 + #define MT6363_RG_VRF13_VOSEL_ADDR 0x1f72 320 + #define MT6363_RG_VRF13_VOSEL_MASK GENMASK(3, 0) 321 + #define MT6363_RG_VRF09_VOCAL_ADDR 0x1f78 322 + #define MT6363_RG_VRF09_VOCAL_MASK GENMASK(3, 0) 323 + #define MT6363_RG_VRF09_VOSEL_ADDR 0x1f79 324 + #define MT6363_RG_VRF09_VOSEL_MASK GENMASK(3, 0) 325 + #define MT6363_ISINK_EN_CTRL0 0x21db 326 + #define MT6363_ISINK_CTRL0_MASK GENMASK(7, 0) 327 + #define MT6363_ISINK_EN_CTRL1 0x21dc 328 + #define MT6363_ISINK_CTRL1_MASK GENMASK(7, 4) 329 + 330 + #endif /* __LINUX_REGULATOR_MT6363_H */