xref: /linux/drivers/regulator/mt6315-regulator.c (revision a4eb44a6435d6d8f9e642407a4a06f65eb90ca04)
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Copyright (c) 2021 MediaTek Inc.
4 
5 #include <linux/module.h>
6 #include <linux/of_device.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>
13 
14 #define MT6315_BUCK_MODE_AUTO		0
15 #define MT6315_BUCK_MODE_FORCE_PWM	1
16 #define MT6315_BUCK_MODE_LP		2
17 
18 struct mt6315_regulator_info {
19 	struct regulator_desc desc;
20 	u32 status_reg;
21 	u32 lp_mode_mask;
22 	u32 lp_mode_shift;
23 };
24 
25 struct mt_regulator_init_data {
26 	u32 modeset_mask[MT6315_VBUCK_MAX];
27 };
28 
29 struct mt6315_chip {
30 	struct device *dev;
31 	struct regmap *regmap;
32 };
33 
34 #define MT_BUCK(_name, _bid, _vsel)				\
35 [_bid] = {							\
36 	.desc = {						\
37 		.name = _name,					\
38 		.of_match = of_match_ptr(_name),		\
39 		.regulators_node = "regulators",		\
40 		.ops = &mt6315_volt_range_ops,			\
41 		.type = REGULATOR_VOLTAGE,			\
42 		.id = _bid,					\
43 		.owner = THIS_MODULE,				\
44 		.n_voltages = 0xc0,				\
45 		.linear_ranges = mt_volt_range1,		\
46 		.n_linear_ranges = ARRAY_SIZE(mt_volt_range1),	\
47 		.vsel_reg = _vsel,				\
48 		.vsel_mask = 0xff,				\
49 		.enable_reg = MT6315_BUCK_TOP_CON0,		\
50 		.enable_mask = BIT(_bid),			\
51 		.of_map_mode = mt6315_map_mode,			\
52 	},							\
53 	.status_reg = _bid##_DBG4,				\
54 	.lp_mode_mask = BIT(_bid),				\
55 	.lp_mode_shift = _bid,					\
56 }
57 
58 static const struct linear_range mt_volt_range1[] = {
59 	REGULATOR_LINEAR_RANGE(0, 0, 0xbf, 6250),
60 };
61 
62 static unsigned int mt6315_map_mode(unsigned int mode)
63 {
64 	switch (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;
71 	default:
72 		return REGULATOR_MODE_INVALID;
73 	}
74 }
75 
76 static unsigned int mt6315_regulator_get_mode(struct regulator_dev *rdev)
77 {
78 	struct mt_regulator_init_data *init = rdev_get_drvdata(rdev);
79 	const struct mt6315_regulator_info *info;
80 	int ret, regval;
81 	u32 modeset_mask;
82 
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, &regval);
86 	if (ret != 0) {
87 		dev_err(&rdev->dev, "Failed to get mode: %d\n", ret);
88 		return ret;
89 	}
90 
91 	if ((regval & modeset_mask) == modeset_mask)
92 		return REGULATOR_MODE_FAST;
93 
94 	ret = regmap_read(rdev->regmap, MT6315_BUCK_TOP_CON1, &regval);
95 	if (ret != 0) {
96 		dev_err(&rdev->dev, "Failed to get lp mode: %d\n", ret);
97 		return ret;
98 	}
99 
100 	if (regval & info->lp_mode_mask)
101 		return REGULATOR_MODE_IDLE;
102 	else
103 		return REGULATOR_MODE_NORMAL;
104 }
105 
106 static int mt6315_regulator_set_mode(struct regulator_dev *rdev,
107 				     u32 mode)
108 {
109 	struct mt_regulator_init_data *init = rdev_get_drvdata(rdev);
110 	const struct mt6315_regulator_info *info;
111 	int ret, val, curr_mode;
112 	u32 modeset_mask;
113 
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);
117 	switch (mode) {
118 	case REGULATOR_MODE_FAST:
119 		ret = regmap_update_bits(rdev->regmap,
120 					 MT6315_BUCK_TOP_4PHASE_ANA_CON42,
121 					 modeset_mask,
122 					 modeset_mask);
123 		break;
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,
128 						 modeset_mask,
129 						 0);
130 		} else if (curr_mode == REGULATOR_MODE_IDLE) {
131 			ret = regmap_update_bits(rdev->regmap,
132 						 MT6315_BUCK_TOP_CON1,
133 						 info->lp_mode_mask,
134 						 0);
135 			usleep_range(100, 110);
136 		} else {
137 			ret = -EINVAL;
138 		}
139 		break;
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,
145 					 info->lp_mode_mask,
146 					 val);
147 		break;
148 	default:
149 		ret = -EINVAL;
150 		dev_err(&rdev->dev, "Unsupported mode: %d\n", mode);
151 		break;
152 	}
153 
154 	if (ret != 0) {
155 		dev_err(&rdev->dev, "Failed to set mode: %d\n", ret);
156 		return ret;
157 	}
158 
159 	return 0;
160 }
161 
162 static int mt6315_get_status(struct regulator_dev *rdev)
163 {
164 	const struct mt6315_regulator_info *info;
165 	int ret;
166 	u32 regval;
167 
168 	info = container_of(rdev->desc, struct mt6315_regulator_info, desc);
169 	ret = regmap_read(rdev->regmap, info->status_reg, &regval);
170 	if (ret < 0) {
171 		dev_err(&rdev->dev, "Failed to get enable reg: %d\n", ret);
172 		return ret;
173 	}
174 
175 	return (regval & BIT(0)) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF;
176 }
177 
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,
190 };
191 
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),
197 };
198 
199 static const struct regmap_config mt6315_regmap_config = {
200 	.reg_bits	= 16,
201 	.val_bits	= 8,
202 	.max_register	= 0x16d0,
203 	.fast_io	= true,
204 };
205 
206 static const struct of_device_id mt6315_of_match[] = {
207 	{
208 		.compatible = "mediatek,mt6315-regulator",
209 	}, {
210 		/* sentinel */
211 	},
212 };
213 MODULE_DEVICE_TABLE(of, mt6315_of_match);
214 
215 static int mt6315_regulator_probe(struct spmi_device *pdev)
216 {
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;
223 	int i;
224 
225 	regmap = devm_regmap_init_spmi_ext(pdev, &mt6315_regmap_config);
226 	if (IS_ERR(regmap))
227 		return PTR_ERR(regmap);
228 
229 	chip = devm_kzalloc(dev, sizeof(struct mt6315_chip), GFP_KERNEL);
230 	if (!chip)
231 		return -ENOMEM;
232 
233 	init_data = devm_kzalloc(dev, sizeof(struct mt_regulator_init_data), GFP_KERNEL);
234 	if (!init_data)
235 		return -ENOMEM;
236 
237 	switch (pdev->usid) {
238 	case MT6315_PP:
239 		init_data->modeset_mask[MT6315_VBUCK1] = BIT(MT6315_VBUCK1) | BIT(MT6315_VBUCK2) |
240 							 BIT(MT6315_VBUCK4);
241 		break;
242 	case MT6315_SP:
243 	case MT6315_RP:
244 		init_data->modeset_mask[MT6315_VBUCK1] = BIT(MT6315_VBUCK1) | BIT(MT6315_VBUCK2);
245 		break;
246 	default:
247 		init_data->modeset_mask[MT6315_VBUCK1] = BIT(MT6315_VBUCK1);
248 		break;
249 	}
250 	for (i = MT6315_VBUCK2; i < MT6315_VBUCK_MAX; i++)
251 		init_data->modeset_mask[i] = BIT(i);
252 
253 	chip->dev = dev;
254 	chip->regmap = regmap;
255 	dev_set_drvdata(dev, chip);
256 
257 	config.dev = dev;
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);
262 		if (IS_ERR(rdev)) {
263 			dev_err(dev, "Failed to register %s\n",
264 				mt6315_regulators[i].desc.name);
265 			return PTR_ERR(rdev);
266 		}
267 	}
268 
269 	return 0;
270 }
271 
272 static void mt6315_regulator_shutdown(struct spmi_device *pdev)
273 {
274 	struct mt6315_chip *chip = dev_get_drvdata(&pdev->dev);
275 	int ret = 0;
276 
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);
282 	if (ret < 0)
283 		dev_err(&pdev->dev, "[%#x] Failed to enable power off sequence. %d\n",
284 			   pdev->usid, ret);
285 }
286 
287 static struct spmi_driver mt6315_regulator_driver = {
288 	.driver		= {
289 		.name	= "mt6315-regulator",
290 		.of_match_table = mt6315_of_match,
291 	},
292 	.probe = mt6315_regulator_probe,
293 	.shutdown = mt6315_regulator_shutdown,
294 };
295 
296 module_spmi_driver(mt6315_regulator_driver);
297 
298 MODULE_AUTHOR("Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>");
299 MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6315 PMIC");
300 MODULE_LICENSE("GPL");
301