1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Copyright (c) 2019 MediaTek Inc.
4 
5 #include <linux/mfd/mt6358/registers.h>
6 #include <linux/mfd/mt6397/core.h>
7 #include <linux/module.h>
8 #include <linux/of.h>
9 #include <linux/platform_device.h>
10 #include <linux/regmap.h>
11 #include <linux/regulator/driver.h>
12 #include <linux/regulator/machine.h>
13 #include <linux/regulator/mt6358-regulator.h>
14 #include <linux/regulator/of_regulator.h>
15 
16 #define MT6358_BUCK_MODE_AUTO	0
17 #define MT6358_BUCK_MODE_FORCE_PWM	1
18 
19 /*
20  * MT6358 regulators' information
21  *
22  * @desc: standard fields of regulator description.
23  * @qi: Mask for query enable signal status of regulators
24  */
25 struct mt6358_regulator_info {
26 	struct regulator_desc desc;
27 	u32 status_reg;
28 	u32 qi;
29 	const u32 *index_table;
30 	unsigned int n_table;
31 	u32 vsel_shift;
32 	u32 da_vsel_reg;
33 	u32 da_vsel_mask;
34 	u32 da_vsel_shift;
35 	u32 modeset_reg;
36 	u32 modeset_mask;
37 	u32 modeset_shift;
38 };
39 
40 #define MT6358_BUCK(match, vreg, min, max, step,		\
41 	volt_ranges, vosel_mask, _da_vsel_reg, _da_vsel_mask,	\
42 	_da_vsel_shift, _modeset_reg, _modeset_shift)		\
43 [MT6358_ID_##vreg] = {	\
44 	.desc = {	\
45 		.name = #vreg,	\
46 		.of_match = of_match_ptr(match),	\
47 		.ops = &mt6358_volt_range_ops,	\
48 		.type = REGULATOR_VOLTAGE,	\
49 		.id = MT6358_ID_##vreg,		\
50 		.owner = THIS_MODULE,		\
51 		.n_voltages = ((max) - (min)) / (step) + 1,	\
52 		.linear_ranges = volt_ranges,		\
53 		.n_linear_ranges = ARRAY_SIZE(volt_ranges),	\
54 		.vsel_reg = MT6358_BUCK_##vreg##_ELR0,	\
55 		.vsel_mask = vosel_mask,	\
56 		.enable_reg = MT6358_BUCK_##vreg##_CON0,	\
57 		.enable_mask = BIT(0),	\
58 		.of_map_mode = mt6358_map_mode,	\
59 	},	\
60 	.status_reg = MT6358_BUCK_##vreg##_DBG1,	\
61 	.qi = BIT(0),	\
62 	.da_vsel_reg = _da_vsel_reg,	\
63 	.da_vsel_mask = _da_vsel_mask,	\
64 	.da_vsel_shift = _da_vsel_shift,	\
65 	.modeset_reg = _modeset_reg,	\
66 	.modeset_mask = BIT(_modeset_shift),	\
67 	.modeset_shift = _modeset_shift	\
68 }
69 
70 #define MT6358_LDO(match, vreg, ldo_volt_table,	\
71 	ldo_index_table, enreg, enbit, vosel,	\
72 	vosel_mask, vosel_shift)	\
73 [MT6358_ID_##vreg] = {	\
74 	.desc = {	\
75 		.name = #vreg,	\
76 		.of_match = of_match_ptr(match),	\
77 		.ops = &mt6358_volt_table_ops,	\
78 		.type = REGULATOR_VOLTAGE,	\
79 		.id = MT6358_ID_##vreg,	\
80 		.owner = THIS_MODULE,	\
81 		.n_voltages = ARRAY_SIZE(ldo_volt_table),	\
82 		.volt_table = ldo_volt_table,	\
83 		.vsel_reg = vosel,	\
84 		.vsel_mask = vosel_mask,	\
85 		.enable_reg = enreg,	\
86 		.enable_mask = BIT(enbit),	\
87 	},	\
88 	.status_reg = MT6358_LDO_##vreg##_CON1,	\
89 	.qi = BIT(15),	\
90 	.index_table = ldo_index_table,	\
91 	.n_table = ARRAY_SIZE(ldo_index_table),	\
92 	.vsel_shift = vosel_shift,	\
93 }
94 
95 #define MT6358_LDO1(match, vreg, min, max, step,	\
96 	volt_ranges, _da_vsel_reg, _da_vsel_mask,	\
97 	_da_vsel_shift, vosel, vosel_mask)	\
98 [MT6358_ID_##vreg] = {	\
99 	.desc = {	\
100 		.name = #vreg,	\
101 		.of_match = of_match_ptr(match),	\
102 		.ops = &mt6358_volt_range_ops,	\
103 		.type = REGULATOR_VOLTAGE,	\
104 		.id = MT6358_ID_##vreg,	\
105 		.owner = THIS_MODULE,	\
106 		.n_voltages = ((max) - (min)) / (step) + 1,	\
107 		.linear_ranges = volt_ranges,	\
108 		.n_linear_ranges = ARRAY_SIZE(volt_ranges),	\
109 		.vsel_reg = vosel,	\
110 		.vsel_mask = vosel_mask,	\
111 		.enable_reg = MT6358_LDO_##vreg##_CON0,	\
112 		.enable_mask = BIT(0),	\
113 	},	\
114 	.da_vsel_reg = _da_vsel_reg,	\
115 	.da_vsel_mask = _da_vsel_mask,	\
116 	.da_vsel_shift = _da_vsel_shift,	\
117 	.status_reg = MT6358_LDO_##vreg##_DBG1,	\
118 	.qi = BIT(0),	\
119 }
120 
121 #define MT6358_REG_FIXED(match, vreg,	\
122 	enreg, enbit, volt)	\
123 [MT6358_ID_##vreg] = {	\
124 	.desc = {	\
125 		.name = #vreg,	\
126 		.of_match = of_match_ptr(match),	\
127 		.ops = &mt6358_volt_fixed_ops,	\
128 		.type = REGULATOR_VOLTAGE,	\
129 		.id = MT6358_ID_##vreg,	\
130 		.owner = THIS_MODULE,	\
131 		.n_voltages = 1,	\
132 		.enable_reg = enreg,	\
133 		.enable_mask = BIT(enbit),	\
134 		.min_uV = volt,	\
135 	},	\
136 	.status_reg = MT6358_LDO_##vreg##_CON1,	\
137 	.qi = BIT(15),							\
138 }
139 
140 static const struct regulator_linear_range buck_volt_range1[] = {
141 	REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 6250),
142 };
143 
144 static const struct regulator_linear_range buck_volt_range2[] = {
145 	REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 12500),
146 };
147 
148 static const struct regulator_linear_range buck_volt_range3[] = {
149 	REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000),
150 };
151 
152 static const struct regulator_linear_range buck_volt_range4[] = {
153 	REGULATOR_LINEAR_RANGE(1000000, 0, 0x7f, 12500),
154 };
155 
156 static const u32 vdram2_voltages[] = {
157 	600000, 1800000,
158 };
159 
160 static const u32 vsim_voltages[] = {
161 	1700000, 1800000, 2700000, 3000000, 3100000,
162 };
163 
164 static const u32 vibr_voltages[] = {
165 	1200000, 1300000, 1500000, 1800000,
166 	2000000, 2800000, 3000000, 3300000,
167 };
168 
169 static const u32 vusb_voltages[] = {
170 	3000000, 3100000,
171 };
172 
173 static const u32 vcamd_voltages[] = {
174 	900000, 1000000, 1100000, 1200000,
175 	1300000, 1500000, 1800000,
176 };
177 
178 static const u32 vefuse_voltages[] = {
179 	1700000, 1800000, 1900000,
180 };
181 
182 static const u32 vmch_vemc_voltages[] = {
183 	2900000, 3000000, 3300000,
184 };
185 
186 static const u32 vcama_voltages[] = {
187 	1800000, 2500000, 2700000,
188 	2800000, 2900000, 3000000,
189 };
190 
191 static const u32 vcn33_bt_wifi_voltages[] = {
192 	3300000, 3400000, 3500000,
193 };
194 
195 static const u32 vmc_voltages[] = {
196 	1800000, 2900000, 3000000, 3300000,
197 };
198 
199 static const u32 vldo28_voltages[] = {
200 	2800000, 3000000,
201 };
202 
203 static const u32 vdram2_idx[] = {
204 	0, 12,
205 };
206 
207 static const u32 vsim_idx[] = {
208 	3, 4, 8, 11, 12,
209 };
210 
211 static const u32 vibr_idx[] = {
212 	0, 1, 2, 4, 5, 9, 11, 13,
213 };
214 
215 static const u32 vusb_idx[] = {
216 	3, 4,
217 };
218 
219 static const u32 vcamd_idx[] = {
220 	3, 4, 5, 6, 7, 9, 12,
221 };
222 
223 static const u32 vefuse_idx[] = {
224 	11, 12, 13,
225 };
226 
227 static const u32 vmch_vemc_idx[] = {
228 	2, 3, 5,
229 };
230 
231 static const u32 vcama_idx[] = {
232 	0, 7, 9, 10, 11, 12,
233 };
234 
235 static const u32 vcn33_bt_wifi_idx[] = {
236 	1, 2, 3,
237 };
238 
239 static const u32 vmc_idx[] = {
240 	4, 10, 11, 13,
241 };
242 
243 static const u32 vldo28_idx[] = {
244 	1, 3,
245 };
246 
247 static unsigned int mt6358_map_mode(unsigned int mode)
248 {
249 	return mode == MT6358_BUCK_MODE_AUTO ?
250 		REGULATOR_MODE_NORMAL : REGULATOR_MODE_FAST;
251 }
252 
253 static int mt6358_set_voltage_sel(struct regulator_dev *rdev,
254 				  unsigned int selector)
255 {
256 	int idx, ret;
257 	const u32 *pvol;
258 	struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
259 
260 	pvol = info->index_table;
261 
262 	idx = pvol[selector];
263 	ret = regmap_update_bits(rdev->regmap, info->desc.vsel_reg,
264 				 info->desc.vsel_mask,
265 				 idx << info->vsel_shift);
266 
267 	return ret;
268 }
269 
270 static int mt6358_get_voltage_sel(struct regulator_dev *rdev)
271 {
272 	int idx, ret;
273 	u32 selector;
274 	struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
275 	const u32 *pvol;
276 
277 	ret = regmap_read(rdev->regmap, info->desc.vsel_reg, &selector);
278 	if (ret != 0) {
279 		dev_info(&rdev->dev,
280 			 "Failed to get mt6358 %s vsel reg: %d\n",
281 			 info->desc.name, ret);
282 		return ret;
283 	}
284 
285 	selector = (selector & info->desc.vsel_mask) >> info->vsel_shift;
286 	pvol = info->index_table;
287 	for (idx = 0; idx < info->desc.n_voltages; idx++) {
288 		if (pvol[idx] == selector)
289 			return idx;
290 	}
291 
292 	return -EINVAL;
293 }
294 
295 static int mt6358_get_buck_voltage_sel(struct regulator_dev *rdev)
296 {
297 	int ret, regval;
298 	struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
299 
300 	ret = regmap_read(rdev->regmap, info->da_vsel_reg, &regval);
301 	if (ret != 0) {
302 		dev_err(&rdev->dev,
303 			"Failed to get mt6358 Buck %s vsel reg: %d\n",
304 			info->desc.name, ret);
305 		return ret;
306 	}
307 
308 	ret = (regval >> info->da_vsel_shift) & info->da_vsel_mask;
309 
310 	return ret;
311 }
312 
313 static int mt6358_get_status(struct regulator_dev *rdev)
314 {
315 	int ret;
316 	u32 regval;
317 	struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
318 
319 	ret = regmap_read(rdev->regmap, info->status_reg, &regval);
320 	if (ret != 0) {
321 		dev_info(&rdev->dev, "Failed to get enable reg: %d\n", ret);
322 		return ret;
323 	}
324 
325 	return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF;
326 }
327 
328 static int mt6358_regulator_set_mode(struct regulator_dev *rdev,
329 				     unsigned int mode)
330 {
331 	struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
332 	int val;
333 
334 	switch (mode) {
335 	case REGULATOR_MODE_FAST:
336 		val = MT6358_BUCK_MODE_FORCE_PWM;
337 		break;
338 	case REGULATOR_MODE_NORMAL:
339 		val = MT6358_BUCK_MODE_AUTO;
340 		break;
341 	default:
342 		return -EINVAL;
343 	}
344 
345 	dev_dbg(&rdev->dev, "mt6358 buck set_mode %#x, %#x, %#x, %#x\n",
346 		info->modeset_reg, info->modeset_mask,
347 		info->modeset_shift, val);
348 
349 	val <<= info->modeset_shift;
350 
351 	return regmap_update_bits(rdev->regmap, info->modeset_reg,
352 				  info->modeset_mask, val);
353 }
354 
355 static unsigned int mt6358_regulator_get_mode(struct regulator_dev *rdev)
356 {
357 	struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
358 	int ret, regval;
359 
360 	ret = regmap_read(rdev->regmap, info->modeset_reg, &regval);
361 	if (ret != 0) {
362 		dev_err(&rdev->dev,
363 			"Failed to get mt6358 buck mode: %d\n", ret);
364 		return ret;
365 	}
366 
367 	switch ((regval & info->modeset_mask) >> info->modeset_shift) {
368 	case MT6358_BUCK_MODE_AUTO:
369 		return REGULATOR_MODE_NORMAL;
370 	case MT6358_BUCK_MODE_FORCE_PWM:
371 		return REGULATOR_MODE_FAST;
372 	default:
373 		return -EINVAL;
374 	}
375 }
376 
377 static const struct regulator_ops mt6358_volt_range_ops = {
378 	.list_voltage = regulator_list_voltage_linear_range,
379 	.map_voltage = regulator_map_voltage_linear_range,
380 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
381 	.get_voltage_sel = mt6358_get_buck_voltage_sel,
382 	.set_voltage_time_sel = regulator_set_voltage_time_sel,
383 	.enable = regulator_enable_regmap,
384 	.disable = regulator_disable_regmap,
385 	.is_enabled = regulator_is_enabled_regmap,
386 	.get_status = mt6358_get_status,
387 	.set_mode = mt6358_regulator_set_mode,
388 	.get_mode = mt6358_regulator_get_mode,
389 };
390 
391 static const struct regulator_ops mt6358_volt_table_ops = {
392 	.list_voltage = regulator_list_voltage_table,
393 	.map_voltage = regulator_map_voltage_iterate,
394 	.set_voltage_sel = mt6358_set_voltage_sel,
395 	.get_voltage_sel = mt6358_get_voltage_sel,
396 	.set_voltage_time_sel = regulator_set_voltage_time_sel,
397 	.enable = regulator_enable_regmap,
398 	.disable = regulator_disable_regmap,
399 	.is_enabled = regulator_is_enabled_regmap,
400 	.get_status = mt6358_get_status,
401 };
402 
403 static const struct regulator_ops mt6358_volt_fixed_ops = {
404 	.list_voltage = regulator_list_voltage_linear,
405 	.enable = regulator_enable_regmap,
406 	.disable = regulator_disable_regmap,
407 	.is_enabled = regulator_is_enabled_regmap,
408 	.get_status = mt6358_get_status,
409 };
410 
411 /* The array is indexed by id(MT6358_ID_XXX) */
412 static struct mt6358_regulator_info mt6358_regulators[] = {
413 	MT6358_BUCK("buck_vdram1", VDRAM1, 500000, 2087500, 12500,
414 		    buck_volt_range2, 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f,
415 		    0, MT6358_VDRAM1_ANA_CON0, 8),
416 	MT6358_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250,
417 		    buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f,
418 		    0, MT6358_VCORE_VGPU_ANA_CON0, 1),
419 	MT6358_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
420 		    buck_volt_range3, 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, 0,
421 		    MT6358_VPA_ANA_CON0, 3),
422 	MT6358_BUCK("buck_vproc11", VPROC11, 500000, 1293750, 6250,
423 		    buck_volt_range1, 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f,
424 		    0, MT6358_VPROC_ANA_CON0, 1),
425 	MT6358_BUCK("buck_vproc12", VPROC12, 500000, 1293750, 6250,
426 		    buck_volt_range1, 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f,
427 		    0, MT6358_VPROC_ANA_CON0, 2),
428 	MT6358_BUCK("buck_vgpu", VGPU, 500000, 1293750, 6250,
429 		    buck_volt_range1, 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, 0,
430 		    MT6358_VCORE_VGPU_ANA_CON0, 2),
431 	MT6358_BUCK("buck_vs2", VS2, 500000, 2087500, 12500,
432 		    buck_volt_range2, 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, 0,
433 		    MT6358_VS2_ANA_CON0, 8),
434 	MT6358_BUCK("buck_vmodem", VMODEM, 500000, 1293750, 6250,
435 		    buck_volt_range1, 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f,
436 		    0, MT6358_VMODEM_ANA_CON0, 8),
437 	MT6358_BUCK("buck_vs1", VS1, 1000000, 2587500, 12500,
438 		    buck_volt_range4, 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, 0,
439 		    MT6358_VS1_ANA_CON0, 8),
440 	MT6358_REG_FIXED("ldo_vrf12", VRF12,
441 			 MT6358_LDO_VRF12_CON0, 0, 1200000),
442 	MT6358_REG_FIXED("ldo_vio18", VIO18,
443 			 MT6358_LDO_VIO18_CON0, 0, 1800000),
444 	MT6358_REG_FIXED("ldo_vcamio", VCAMIO,
445 			 MT6358_LDO_VCAMIO_CON0, 0, 1800000),
446 	MT6358_REG_FIXED("ldo_vcn18", VCN18, MT6358_LDO_VCN18_CON0, 0, 1800000),
447 	MT6358_REG_FIXED("ldo_vfe28", VFE28, MT6358_LDO_VFE28_CON0, 0, 2800000),
448 	MT6358_REG_FIXED("ldo_vcn28", VCN28, MT6358_LDO_VCN28_CON0, 0, 2800000),
449 	MT6358_REG_FIXED("ldo_vxo22", VXO22, MT6358_LDO_VXO22_CON0, 0, 2200000),
450 	MT6358_REG_FIXED("ldo_vaux18", VAUX18,
451 			 MT6358_LDO_VAUX18_CON0, 0, 1800000),
452 	MT6358_REG_FIXED("ldo_vbif28", VBIF28,
453 			 MT6358_LDO_VBIF28_CON0, 0, 2800000),
454 	MT6358_REG_FIXED("ldo_vio28", VIO28, MT6358_LDO_VIO28_CON0, 0, 2800000),
455 	MT6358_REG_FIXED("ldo_va12", VA12, MT6358_LDO_VA12_CON0, 0, 1200000),
456 	MT6358_REG_FIXED("ldo_vrf18", VRF18, MT6358_LDO_VRF18_CON0, 0, 1800000),
457 	MT6358_REG_FIXED("ldo_vaud28", VAUD28,
458 			 MT6358_LDO_VAUD28_CON0, 0, 2800000),
459 	MT6358_LDO("ldo_vdram2", VDRAM2, vdram2_voltages, vdram2_idx,
460 		   MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0x10, 0),
461 	MT6358_LDO("ldo_vsim1", VSIM1, vsim_voltages, vsim_idx,
462 		   MT6358_LDO_VSIM1_CON0, 0, MT6358_VSIM1_ANA_CON0, 0xf00, 8),
463 	MT6358_LDO("ldo_vibr", VIBR, vibr_voltages, vibr_idx,
464 		   MT6358_LDO_VIBR_CON0, 0, MT6358_VIBR_ANA_CON0, 0xf00, 8),
465 	MT6358_LDO("ldo_vusb", VUSB, vusb_voltages, vusb_idx,
466 		   MT6358_LDO_VUSB_CON0_0, 0, MT6358_VUSB_ANA_CON0, 0x700, 8),
467 	MT6358_LDO("ldo_vcamd", VCAMD, vcamd_voltages, vcamd_idx,
468 		   MT6358_LDO_VCAMD_CON0, 0, MT6358_VCAMD_ANA_CON0, 0xf00, 8),
469 	MT6358_LDO("ldo_vefuse", VEFUSE, vefuse_voltages, vefuse_idx,
470 		   MT6358_LDO_VEFUSE_CON0, 0, MT6358_VEFUSE_ANA_CON0, 0xf00, 8),
471 	MT6358_LDO("ldo_vmch", VMCH, vmch_vemc_voltages, vmch_vemc_idx,
472 		   MT6358_LDO_VMCH_CON0, 0, MT6358_VMCH_ANA_CON0, 0x700, 8),
473 	MT6358_LDO("ldo_vcama1", VCAMA1, vcama_voltages, vcama_idx,
474 		   MT6358_LDO_VCAMA1_CON0, 0, MT6358_VCAMA1_ANA_CON0, 0xf00, 8),
475 	MT6358_LDO("ldo_vemc", VEMC, vmch_vemc_voltages, vmch_vemc_idx,
476 		   MT6358_LDO_VEMC_CON0, 0, MT6358_VEMC_ANA_CON0, 0x700, 8),
477 	MT6358_LDO("ldo_vcn33_bt", VCN33_BT, vcn33_bt_wifi_voltages,
478 		   vcn33_bt_wifi_idx, MT6358_LDO_VCN33_CON0_0,
479 		   0, MT6358_VCN33_ANA_CON0, 0x300, 8),
480 	MT6358_LDO("ldo_vcn33_wifi", VCN33_WIFI, vcn33_bt_wifi_voltages,
481 		   vcn33_bt_wifi_idx, MT6358_LDO_VCN33_CON0_1,
482 		   0, MT6358_VCN33_ANA_CON0, 0x300, 8),
483 	MT6358_LDO("ldo_vcama2", VCAMA2, vcama_voltages, vcama_idx,
484 		   MT6358_LDO_VCAMA2_CON0, 0, MT6358_VCAMA2_ANA_CON0, 0xf00, 8),
485 	MT6358_LDO("ldo_vmc", VMC, vmc_voltages, vmc_idx,
486 		   MT6358_LDO_VMC_CON0, 0, MT6358_VMC_ANA_CON0, 0xf00, 8),
487 	MT6358_LDO("ldo_vldo28", VLDO28, vldo28_voltages, vldo28_idx,
488 		   MT6358_LDO_VLDO28_CON0_0, 0,
489 		   MT6358_VLDO28_ANA_CON0, 0x300, 8),
490 	MT6358_LDO("ldo_vsim2", VSIM2, vsim_voltages, vsim_idx,
491 		   MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00, 8),
492 	MT6358_LDO1("ldo_vsram_proc11", VSRAM_PROC11, 500000, 1293750, 6250,
493 		    buck_volt_range1, MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f, 8,
494 		    MT6358_LDO_VSRAM_CON0, 0x7f),
495 	MT6358_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250,
496 		    buck_volt_range1, MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f, 8,
497 		    MT6358_LDO_VSRAM_CON2, 0x7f),
498 	MT6358_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250,
499 		    buck_volt_range1, MT6358_LDO_VSRAM_GPU_DBG0, 0x7f, 8,
500 		    MT6358_LDO_VSRAM_CON3, 0x7f),
501 	MT6358_LDO1("ldo_vsram_proc12", VSRAM_PROC12, 500000, 1293750, 6250,
502 		    buck_volt_range1, MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f, 8,
503 		    MT6358_LDO_VSRAM_CON1, 0x7f),
504 };
505 
506 static int mt6358_regulator_probe(struct platform_device *pdev)
507 {
508 	struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);
509 	struct regulator_config config = {};
510 	struct regulator_dev *rdev;
511 	int i;
512 
513 	for (i = 0; i < MT6358_MAX_REGULATOR; i++) {
514 		config.dev = &pdev->dev;
515 		config.driver_data = &mt6358_regulators[i];
516 		config.regmap = mt6397->regmap;
517 
518 		rdev = devm_regulator_register(&pdev->dev,
519 					       &mt6358_regulators[i].desc,
520 					       &config);
521 		if (IS_ERR(rdev)) {
522 			dev_err(&pdev->dev, "failed to register %s\n",
523 				mt6358_regulators[i].desc.name);
524 			return PTR_ERR(rdev);
525 		}
526 	}
527 
528 	return 0;
529 }
530 
531 static const struct platform_device_id mt6358_platform_ids[] = {
532 	{"mt6358-regulator", 0},
533 	{ /* sentinel */ },
534 };
535 MODULE_DEVICE_TABLE(platform, mt6358_platform_ids);
536 
537 static struct platform_driver mt6358_regulator_driver = {
538 	.driver = {
539 		.name = "mt6358-regulator",
540 	},
541 	.probe = mt6358_regulator_probe,
542 	.id_table = mt6358_platform_ids,
543 };
544 
545 module_platform_driver(mt6358_regulator_driver);
546 
547 MODULE_AUTHOR("Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>");
548 MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6358 PMIC");
549 MODULE_LICENSE("GPL");
550