1 // SPDX-License-Identifier: GPL-2.0
3 // Copyright (c) 2021 MediaTek Inc.
5 #include <linux/module.h>
7 #include <linux/regmap.h>
8 #include <linux/regulator/driver.h>
9 #include <linux/regulator/machine.h>
10 #include <linux/regulator/mt6315-regulator.h>
11 #include <linux/regulator/of_regulator.h>
12 #include <linux/spmi.h>
14 #define MT6315_BUCK_MODE_AUTO 0
15 #define MT6315_BUCK_MODE_FORCE_PWM 1
16 #define MT6315_BUCK_MODE_LP 2
18 struct mt6315_regulator_info
{
19 struct regulator_desc desc
;
25 struct mt_regulator_init_data
{
26 u32 modeset_mask
[MT6315_VBUCK_MAX
];
31 struct regmap
*regmap
;
34 #define MT_BUCK(_name, _bid, _vsel) \
38 .of_match = of_match_ptr(_name), \
39 .regulators_node = "regulators", \
40 .ops = &mt6315_volt_range_ops, \
41 .type = REGULATOR_VOLTAGE, \
43 .owner = THIS_MODULE, \
45 .linear_ranges = mt_volt_range1, \
46 .n_linear_ranges = ARRAY_SIZE(mt_volt_range1), \
49 .enable_reg = MT6315_BUCK_TOP_CON0, \
50 .enable_mask = BIT(_bid), \
51 .of_map_mode = mt6315_map_mode, \
53 .status_reg = _bid##_DBG4, \
54 .lp_mode_mask = BIT(_bid), \
55 .lp_mode_shift = _bid, \
58 static const struct linear_range mt_volt_range1
[] = {
59 REGULATOR_LINEAR_RANGE(0, 0, 0xbf, 6250),
62 static unsigned int mt6315_map_mode(unsigned int mode
)
65 case MT6315_BUCK_MODE_AUTO
:
66 return REGULATOR_MODE_NORMAL
;
67 case MT6315_BUCK_MODE_FORCE_PWM
:
68 return REGULATOR_MODE_FAST
;
69 case MT6315_BUCK_MODE_LP
:
70 return REGULATOR_MODE_IDLE
;
72 return REGULATOR_MODE_INVALID
;
76 static unsigned int mt6315_regulator_get_mode(struct regulator_dev
*rdev
)
78 struct mt_regulator_init_data
*init
= rdev_get_drvdata(rdev
);
79 const struct mt6315_regulator_info
*info
;
83 info
= container_of(rdev
->desc
, struct mt6315_regulator_info
, desc
);
84 modeset_mask
= init
->modeset_mask
[rdev_get_id(rdev
)];
85 ret
= regmap_read(rdev
->regmap
, MT6315_BUCK_TOP_4PHASE_ANA_CON42
, ®val
);
87 dev_err(&rdev
->dev
, "Failed to get mode: %d\n", ret
);
91 if ((regval
& modeset_mask
) == modeset_mask
)
92 return REGULATOR_MODE_FAST
;
94 ret
= regmap_read(rdev
->regmap
, MT6315_BUCK_TOP_CON1
, ®val
);
96 dev_err(&rdev
->dev
, "Failed to get lp mode: %d\n", ret
);
100 if (regval
& info
->lp_mode_mask
)
101 return REGULATOR_MODE_IDLE
;
103 return REGULATOR_MODE_NORMAL
;
106 static int mt6315_regulator_set_mode(struct regulator_dev
*rdev
,
109 struct mt_regulator_init_data
*init
= rdev_get_drvdata(rdev
);
110 const struct mt6315_regulator_info
*info
;
111 int ret
, val
, curr_mode
;
114 info
= container_of(rdev
->desc
, struct mt6315_regulator_info
, desc
);
115 modeset_mask
= init
->modeset_mask
[rdev_get_id(rdev
)];
116 curr_mode
= mt6315_regulator_get_mode(rdev
);
118 case REGULATOR_MODE_FAST
:
119 ret
= regmap_update_bits(rdev
->regmap
,
120 MT6315_BUCK_TOP_4PHASE_ANA_CON42
,
124 case REGULATOR_MODE_NORMAL
:
125 if (curr_mode
== REGULATOR_MODE_FAST
) {
126 ret
= regmap_update_bits(rdev
->regmap
,
127 MT6315_BUCK_TOP_4PHASE_ANA_CON42
,
130 } else if (curr_mode
== REGULATOR_MODE_IDLE
) {
131 ret
= regmap_update_bits(rdev
->regmap
,
132 MT6315_BUCK_TOP_CON1
,
135 usleep_range(100, 110);
140 case REGULATOR_MODE_IDLE
:
141 val
= MT6315_BUCK_MODE_LP
>> 1;
142 val
<<= info
->lp_mode_shift
;
143 ret
= regmap_update_bits(rdev
->regmap
,
144 MT6315_BUCK_TOP_CON1
,
150 dev_err(&rdev
->dev
, "Unsupported mode: %d\n", mode
);
155 dev_err(&rdev
->dev
, "Failed to set mode: %d\n", ret
);
162 static int mt6315_get_status(struct regulator_dev
*rdev
)
164 const struct mt6315_regulator_info
*info
;
168 info
= container_of(rdev
->desc
, struct mt6315_regulator_info
, desc
);
169 ret
= regmap_read(rdev
->regmap
, info
->status_reg
, ®val
);
171 dev_err(&rdev
->dev
, "Failed to get enable reg: %d\n", ret
);
175 return (regval
& BIT(0)) ? REGULATOR_STATUS_ON
: REGULATOR_STATUS_OFF
;
178 static const struct regulator_ops mt6315_volt_range_ops
= {
179 .list_voltage
= regulator_list_voltage_linear_range
,
180 .map_voltage
= regulator_map_voltage_linear_range
,
181 .set_voltage_sel
= regulator_set_voltage_sel_regmap
,
182 .get_voltage_sel
= regulator_get_voltage_sel_regmap
,
183 .set_voltage_time_sel
= regulator_set_voltage_time_sel
,
184 .enable
= regulator_enable_regmap
,
185 .disable
= regulator_disable_regmap
,
186 .is_enabled
= regulator_is_enabled_regmap
,
187 .get_status
= mt6315_get_status
,
188 .set_mode
= mt6315_regulator_set_mode
,
189 .get_mode
= mt6315_regulator_get_mode
,
192 static const struct mt6315_regulator_info mt6315_regulators
[MT6315_VBUCK_MAX
] = {
193 MT_BUCK("vbuck1", MT6315_VBUCK1
, MT6315_BUCK_TOP_ELR0
),
194 MT_BUCK("vbuck2", MT6315_VBUCK2
, MT6315_BUCK_TOP_ELR2
),
195 MT_BUCK("vbuck3", MT6315_VBUCK3
, MT6315_BUCK_TOP_ELR4
),
196 MT_BUCK("vbuck4", MT6315_VBUCK4
, MT6315_BUCK_TOP_ELR6
),
199 static const struct regmap_config mt6315_regmap_config
= {
202 .max_register
= 0x16d0,
206 static const struct of_device_id mt6315_of_match
[] = {
208 .compatible
= "mediatek,mt6315-regulator",
213 MODULE_DEVICE_TABLE(of
, mt6315_of_match
);
215 static int mt6315_regulator_probe(struct spmi_device
*pdev
)
217 struct device
*dev
= &pdev
->dev
;
218 struct regmap
*regmap
;
219 struct mt6315_chip
*chip
;
220 struct mt_regulator_init_data
*init_data
;
221 struct regulator_config config
= {};
222 struct regulator_dev
*rdev
;
225 regmap
= devm_regmap_init_spmi_ext(pdev
, &mt6315_regmap_config
);
227 return PTR_ERR(regmap
);
229 chip
= devm_kzalloc(dev
, sizeof(struct mt6315_chip
), GFP_KERNEL
);
233 init_data
= devm_kzalloc(dev
, sizeof(struct mt_regulator_init_data
), GFP_KERNEL
);
237 switch (pdev
->usid
) {
239 init_data
->modeset_mask
[MT6315_VBUCK1
] = BIT(MT6315_VBUCK1
) | BIT(MT6315_VBUCK2
) |
244 init_data
->modeset_mask
[MT6315_VBUCK1
] = BIT(MT6315_VBUCK1
) | BIT(MT6315_VBUCK2
);
247 init_data
->modeset_mask
[MT6315_VBUCK1
] = BIT(MT6315_VBUCK1
);
250 for (i
= MT6315_VBUCK2
; i
< MT6315_VBUCK_MAX
; i
++)
251 init_data
->modeset_mask
[i
] = BIT(i
);
254 chip
->regmap
= regmap
;
255 dev_set_drvdata(dev
, chip
);
258 config
.regmap
= regmap
;
259 for (i
= MT6315_VBUCK1
; i
< MT6315_VBUCK_MAX
; i
++) {
260 config
.driver_data
= init_data
;
261 rdev
= devm_regulator_register(dev
, &mt6315_regulators
[i
].desc
, &config
);
263 dev_err(dev
, "Failed to register %s\n",
264 mt6315_regulators
[i
].desc
.name
);
265 return PTR_ERR(rdev
);
272 static void mt6315_regulator_shutdown(struct spmi_device
*pdev
)
274 struct mt6315_chip
*chip
= dev_get_drvdata(&pdev
->dev
);
277 ret
|= regmap_write(chip
->regmap
, MT6315_TOP_TMA_KEY_H
, PROTECTION_KEY_H
);
278 ret
|= regmap_write(chip
->regmap
, MT6315_TOP_TMA_KEY
, PROTECTION_KEY
);
279 ret
|= regmap_update_bits(chip
->regmap
, MT6315_TOP2_ELR7
, 1, 1);
280 ret
|= regmap_write(chip
->regmap
, MT6315_TOP_TMA_KEY
, 0);
281 ret
|= regmap_write(chip
->regmap
, MT6315_TOP_TMA_KEY_H
, 0);
283 dev_err(&pdev
->dev
, "[%#x] Failed to enable power off sequence. %d\n",
287 static struct spmi_driver mt6315_regulator_driver
= {
289 .name
= "mt6315-regulator",
290 .probe_type
= PROBE_PREFER_ASYNCHRONOUS
,
291 .of_match_table
= mt6315_of_match
,
293 .probe
= mt6315_regulator_probe
,
294 .shutdown
= mt6315_regulator_shutdown
,
297 module_spmi_driver(mt6315_regulator_driver
);
299 MODULE_AUTHOR("Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>");
300 MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6315 PMIC");
301 MODULE_LICENSE("GPL");