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 | #include <dt-bindings/regulator/mediatek,mt6397-regulator.h> |
17 | |
18 | /* |
19 | * MT6358 regulators' information |
20 | * |
21 | * @desc: standard fields of regulator description. |
22 | * @qi: Mask for query enable signal status of regulators |
23 | */ |
24 | struct mt6358_regulator_info { |
25 | struct regulator_desc desc; |
26 | u32 status_reg; |
27 | u32 qi; |
28 | u32 da_vsel_reg; |
29 | u32 da_vsel_mask; |
30 | u32 modeset_reg; |
31 | u32 modeset_mask; |
32 | }; |
33 | |
34 | #define to_regulator_info(x) container_of((x), struct mt6358_regulator_info, desc) |
35 | |
36 | #define MT6358_BUCK(match, vreg, supply, min, max, step, \ |
37 | vosel_mask, _da_vsel_reg, _da_vsel_mask, \ |
38 | _modeset_reg, _modeset_shift) \ |
39 | [MT6358_ID_##vreg] = { \ |
40 | .desc = { \ |
41 | .name = #vreg, \ |
42 | .supply_name = supply, \ |
43 | .of_match = of_match_ptr(match), \ |
44 | .ops = &mt6358_buck_ops, \ |
45 | .type = REGULATOR_VOLTAGE, \ |
46 | .id = MT6358_ID_##vreg, \ |
47 | .owner = THIS_MODULE, \ |
48 | .n_voltages = ((max) - (min)) / (step) + 1, \ |
49 | .min_uV = (min), \ |
50 | .uV_step = (step), \ |
51 | .vsel_reg = MT6358_BUCK_##vreg##_ELR0, \ |
52 | .vsel_mask = vosel_mask, \ |
53 | .enable_reg = MT6358_BUCK_##vreg##_CON0, \ |
54 | .enable_mask = BIT(0), \ |
55 | .of_map_mode = mt6358_map_mode, \ |
56 | }, \ |
57 | .status_reg = MT6358_BUCK_##vreg##_DBG1, \ |
58 | .qi = BIT(0), \ |
59 | .da_vsel_reg = _da_vsel_reg, \ |
60 | .da_vsel_mask = _da_vsel_mask, \ |
61 | .modeset_reg = _modeset_reg, \ |
62 | .modeset_mask = BIT(_modeset_shift), \ |
63 | } |
64 | |
65 | #define MT6358_LDO(match, vreg, supply, volt_ranges, enreg, enbit, vosel, vosel_mask) \ |
66 | [MT6358_ID_##vreg] = { \ |
67 | .desc = { \ |
68 | .name = #vreg, \ |
69 | .supply_name = supply, \ |
70 | .of_match = of_match_ptr(match), \ |
71 | .ops = &mt6358_volt_table_ops, \ |
72 | .type = REGULATOR_VOLTAGE, \ |
73 | .id = MT6358_ID_##vreg, \ |
74 | .owner = THIS_MODULE, \ |
75 | .n_voltages = ARRAY_SIZE(volt_ranges##_ranges) * 11, \ |
76 | .linear_ranges = volt_ranges##_ranges, \ |
77 | .linear_range_selectors_bitfield = volt_ranges##_selectors, \ |
78 | .n_linear_ranges = ARRAY_SIZE(volt_ranges##_ranges), \ |
79 | .vsel_range_reg = vosel, \ |
80 | .vsel_range_mask = vosel_mask, \ |
81 | .vsel_reg = MT6358_##vreg##_ANA_CON0, \ |
82 | .vsel_mask = GENMASK(3, 0), \ |
83 | .enable_reg = enreg, \ |
84 | .enable_mask = BIT(enbit), \ |
85 | }, \ |
86 | .status_reg = MT6358_LDO_##vreg##_CON1, \ |
87 | .qi = BIT(15), \ |
88 | } |
89 | |
90 | #define MT6358_LDO1(match, vreg, supply, min, max, step, \ |
91 | _da_vsel_reg, _da_vsel_mask, vosel, vosel_mask) \ |
92 | [MT6358_ID_##vreg] = { \ |
93 | .desc = { \ |
94 | .name = #vreg, \ |
95 | .supply_name = supply, \ |
96 | .of_match = of_match_ptr(match), \ |
97 | .ops = &mt6358_volt_range_ops, \ |
98 | .type = REGULATOR_VOLTAGE, \ |
99 | .id = MT6358_ID_##vreg, \ |
100 | .owner = THIS_MODULE, \ |
101 | .n_voltages = ((max) - (min)) / (step) + 1, \ |
102 | .min_uV = (min), \ |
103 | .uV_step = (step), \ |
104 | .vsel_reg = vosel, \ |
105 | .vsel_mask = vosel_mask, \ |
106 | .enable_reg = MT6358_LDO_##vreg##_CON0, \ |
107 | .enable_mask = BIT(0), \ |
108 | }, \ |
109 | .da_vsel_reg = _da_vsel_reg, \ |
110 | .da_vsel_mask = _da_vsel_mask, \ |
111 | .status_reg = MT6358_LDO_##vreg##_DBG1, \ |
112 | .qi = BIT(0), \ |
113 | } |
114 | |
115 | #define MT6358_REG_FIXED(match, vreg, supply, enreg, enbit, volt) \ |
116 | [MT6358_ID_##vreg] = { \ |
117 | .desc = { \ |
118 | .name = #vreg, \ |
119 | .supply_name = supply, \ |
120 | .of_match = of_match_ptr(match), \ |
121 | .ops = &mt6358_volt_fixed_ops, \ |
122 | .type = REGULATOR_VOLTAGE, \ |
123 | .id = MT6358_ID_##vreg, \ |
124 | .owner = THIS_MODULE, \ |
125 | .n_voltages = 11, \ |
126 | .vsel_reg = MT6358_##vreg##_ANA_CON0, \ |
127 | .vsel_mask = GENMASK(3, 0), \ |
128 | .enable_reg = enreg, \ |
129 | .enable_mask = BIT(enbit), \ |
130 | .min_uV = volt, \ |
131 | .uV_step = 10000, \ |
132 | }, \ |
133 | .status_reg = MT6358_LDO_##vreg##_CON1, \ |
134 | .qi = BIT(15), \ |
135 | } |
136 | |
137 | #define MT6366_BUCK(match, vreg, min, max, step, \ |
138 | vosel_mask, _da_vsel_reg, _da_vsel_mask, \ |
139 | _modeset_reg, _modeset_shift) \ |
140 | [MT6366_ID_##vreg] = { \ |
141 | .desc = { \ |
142 | .name = #vreg, \ |
143 | .supply_name = "vsys-" match, \ |
144 | .of_match = of_match_ptr(match), \ |
145 | .ops = &mt6358_buck_ops, \ |
146 | .type = REGULATOR_VOLTAGE, \ |
147 | .id = MT6366_ID_##vreg, \ |
148 | .owner = THIS_MODULE, \ |
149 | .n_voltages = ((max) - (min)) / (step) + 1, \ |
150 | .min_uV = (min), \ |
151 | .uV_step = (step), \ |
152 | .vsel_reg = MT6358_BUCK_##vreg##_ELR0, \ |
153 | .vsel_mask = vosel_mask, \ |
154 | .enable_reg = MT6358_BUCK_##vreg##_CON0, \ |
155 | .enable_mask = BIT(0), \ |
156 | .of_map_mode = mt6358_map_mode, \ |
157 | }, \ |
158 | .status_reg = MT6358_BUCK_##vreg##_DBG1, \ |
159 | .qi = BIT(0), \ |
160 | .da_vsel_reg = _da_vsel_reg, \ |
161 | .da_vsel_mask = _da_vsel_mask, \ |
162 | .modeset_reg = _modeset_reg, \ |
163 | .modeset_mask = BIT(_modeset_shift), \ |
164 | } |
165 | |
166 | #define MT6366_LDO(match, vreg, volt_ranges, supply, enreg, enbit, vosel, vosel_mask) \ |
167 | [MT6366_ID_##vreg] = { \ |
168 | .desc = { \ |
169 | .name = #vreg, \ |
170 | .supply_name = supply, \ |
171 | .of_match = of_match_ptr(match), \ |
172 | .ops = &mt6358_volt_table_ops, \ |
173 | .type = REGULATOR_VOLTAGE, \ |
174 | .id = MT6366_ID_##vreg, \ |
175 | .owner = THIS_MODULE, \ |
176 | .n_voltages = ARRAY_SIZE(volt_ranges##_ranges) * 11, \ |
177 | .linear_ranges = volt_ranges##_ranges, \ |
178 | .linear_range_selectors_bitfield = volt_ranges##_selectors, \ |
179 | .n_linear_ranges = ARRAY_SIZE(volt_ranges##_ranges), \ |
180 | .vsel_range_reg = vosel, \ |
181 | .vsel_range_mask = vosel_mask, \ |
182 | .vsel_reg = MT6358_##vreg##_ANA_CON0, \ |
183 | .vsel_mask = GENMASK(3, 0), \ |
184 | .enable_reg = enreg, \ |
185 | .enable_mask = BIT(enbit), \ |
186 | }, \ |
187 | .status_reg = MT6358_LDO_##vreg##_CON1, \ |
188 | .qi = BIT(15), \ |
189 | } |
190 | |
191 | #define MT6366_LDO1(match, vreg, supply, min, max, step, \ |
192 | _da_vsel_reg, _da_vsel_mask, vosel, vosel_mask) \ |
193 | [MT6366_ID_##vreg] = { \ |
194 | .desc = { \ |
195 | .name = #vreg, \ |
196 | .supply_name = supply, \ |
197 | .of_match = of_match_ptr(match), \ |
198 | .ops = &mt6358_volt_range_ops, \ |
199 | .type = REGULATOR_VOLTAGE, \ |
200 | .id = MT6366_ID_##vreg, \ |
201 | .owner = THIS_MODULE, \ |
202 | .n_voltages = ((max) - (min)) / (step) + 1, \ |
203 | .min_uV = (min), \ |
204 | .uV_step = (step), \ |
205 | .vsel_reg = vosel, \ |
206 | .vsel_mask = vosel_mask, \ |
207 | .enable_reg = MT6358_LDO_##vreg##_CON0, \ |
208 | .enable_mask = BIT(0), \ |
209 | }, \ |
210 | .da_vsel_reg = _da_vsel_reg, \ |
211 | .da_vsel_mask = _da_vsel_mask, \ |
212 | .status_reg = MT6358_LDO_##vreg##_DBG1, \ |
213 | .qi = BIT(0), \ |
214 | } |
215 | |
216 | #define MT6366_REG_FIXED(match, vreg, supply, enreg, enbit, volt) \ |
217 | [MT6366_ID_##vreg] = { \ |
218 | .desc = { \ |
219 | .name = #vreg, \ |
220 | .supply_name = supply, \ |
221 | .of_match = of_match_ptr(match), \ |
222 | .ops = &mt6358_volt_fixed_ops, \ |
223 | .type = REGULATOR_VOLTAGE, \ |
224 | .id = MT6366_ID_##vreg, \ |
225 | .owner = THIS_MODULE, \ |
226 | .n_voltages = 11, \ |
227 | .vsel_reg = MT6358_##vreg##_ANA_CON0, \ |
228 | .vsel_mask = GENMASK(3, 0), \ |
229 | .enable_reg = enreg, \ |
230 | .enable_mask = BIT(enbit), \ |
231 | .min_uV = volt, \ |
232 | .uV_step = 10000, \ |
233 | }, \ |
234 | .status_reg = MT6358_LDO_##vreg##_CON1, \ |
235 | .qi = BIT(15), \ |
236 | } |
237 | |
238 | |
239 | /* VDRAM2 voltage selector not shown in datasheet */ |
240 | static const unsigned int vdram2_selectors[] = { 0, 12 }; |
241 | static const struct linear_range vdram2_ranges[] = { |
242 | REGULATOR_LINEAR_RANGE(600000, 0, 10, 10000), |
243 | REGULATOR_LINEAR_RANGE(1800000, 0, 10, 10000), |
244 | }; |
245 | |
246 | static const unsigned int vsim_selectors[] = { 3, 4, 8, 11, 12 }; |
247 | static const struct linear_range vsim_ranges[] = { |
248 | REGULATOR_LINEAR_RANGE(1700000, 0, 10, 10000), |
249 | REGULATOR_LINEAR_RANGE(1800000, 0, 10, 10000), |
250 | REGULATOR_LINEAR_RANGE(2700000, 0, 10, 10000), |
251 | REGULATOR_LINEAR_RANGE(3000000, 0, 10, 10000), |
252 | REGULATOR_LINEAR_RANGE(3100000, 0, 10, 10000), |
253 | }; |
254 | |
255 | static const unsigned int vibr_selectors[] = { 0, 1, 2, 4, 5, 9, 11, 13 }; |
256 | static const struct linear_range vibr_ranges[] = { |
257 | REGULATOR_LINEAR_RANGE(1200000, 0, 10, 10000), |
258 | REGULATOR_LINEAR_RANGE(1300000, 0, 10, 10000), |
259 | REGULATOR_LINEAR_RANGE(1500000, 0, 10, 10000), |
260 | REGULATOR_LINEAR_RANGE(1800000, 0, 10, 10000), |
261 | REGULATOR_LINEAR_RANGE(2000000, 0, 10, 10000), |
262 | REGULATOR_LINEAR_RANGE(2800000, 0, 10, 10000), |
263 | REGULATOR_LINEAR_RANGE(3000000, 0, 10, 10000), |
264 | REGULATOR_LINEAR_RANGE(3300000, 0, 10, 10000), |
265 | }; |
266 | |
267 | /* VUSB voltage selector not shown in datasheet */ |
268 | static const unsigned int vusb_selectors[] = { 3, 4 }; |
269 | static const struct linear_range vusb_ranges[] = { |
270 | REGULATOR_LINEAR_RANGE(3000000, 0, 10, 10000), |
271 | REGULATOR_LINEAR_RANGE(3100000, 0, 10, 10000), |
272 | }; |
273 | |
274 | static const unsigned int vcamd_selectors[] = { 3, 4, 5, 6, 7, 9, 12 }; |
275 | static const struct linear_range vcamd_ranges[] = { |
276 | REGULATOR_LINEAR_RANGE(900000, 0, 10, 10000), |
277 | REGULATOR_LINEAR_RANGE(1000000, 0, 10, 10000), |
278 | REGULATOR_LINEAR_RANGE(1100000, 0, 10, 10000), |
279 | REGULATOR_LINEAR_RANGE(1200000, 0, 10, 10000), |
280 | REGULATOR_LINEAR_RANGE(1300000, 0, 10, 10000), |
281 | REGULATOR_LINEAR_RANGE(1500000, 0, 10, 10000), |
282 | REGULATOR_LINEAR_RANGE(1800000, 0, 10, 10000), |
283 | }; |
284 | |
285 | static const unsigned int vefuse_selectors[] = { 11, 12, 13 }; |
286 | static const struct linear_range vefuse_ranges[] = { |
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 | }; |
291 | |
292 | static const unsigned int vmch_vemc_selectors[] = { 2, 3, 5 }; |
293 | static const struct linear_range vmch_vemc_ranges[] = { |
294 | REGULATOR_LINEAR_RANGE(2900000, 0, 10, 10000), |
295 | REGULATOR_LINEAR_RANGE(3000000, 0, 10, 10000), |
296 | REGULATOR_LINEAR_RANGE(3300000, 0, 10, 10000), |
297 | }; |
298 | |
299 | static const unsigned int vcama_selectors[] = { 0, 7, 9, 10, 11, 12 }; |
300 | static const struct linear_range vcama_ranges[] = { |
301 | REGULATOR_LINEAR_RANGE(1800000, 0, 10, 10000), |
302 | REGULATOR_LINEAR_RANGE(2500000, 0, 10, 10000), |
303 | REGULATOR_LINEAR_RANGE(2700000, 0, 10, 10000), |
304 | REGULATOR_LINEAR_RANGE(2800000, 0, 10, 10000), |
305 | REGULATOR_LINEAR_RANGE(2900000, 0, 10, 10000), |
306 | REGULATOR_LINEAR_RANGE(3000000, 0, 10, 10000), |
307 | }; |
308 | |
309 | static const unsigned int vcn33_selectors[] = { 1, 2, 3 }; |
310 | static const struct linear_range vcn33_ranges[] = { |
311 | REGULATOR_LINEAR_RANGE(3300000, 0, 10, 10000), |
312 | REGULATOR_LINEAR_RANGE(3400000, 0, 10, 10000), |
313 | REGULATOR_LINEAR_RANGE(3500000, 0, 10, 10000), |
314 | }; |
315 | |
316 | static const unsigned int vmc_selectors[] = { 4, 10, 11, 13 }; |
317 | static const struct linear_range vmc_ranges[] = { |
318 | REGULATOR_LINEAR_RANGE(1800000, 0, 10, 10000), |
319 | REGULATOR_LINEAR_RANGE(2900000, 0, 10, 10000), |
320 | REGULATOR_LINEAR_RANGE(3000000, 0, 10, 10000), |
321 | REGULATOR_LINEAR_RANGE(3300000, 0, 10, 10000), |
322 | }; |
323 | |
324 | static const unsigned int vldo28_selectors[] = { 1, 3 }; |
325 | static const struct linear_range vldo28_ranges[] = { |
326 | REGULATOR_LINEAR_RANGE(2800000, 0, 10, 10000), |
327 | REGULATOR_LINEAR_RANGE(3000000, 0, 10, 10000), |
328 | }; |
329 | |
330 | static const unsigned int mt6366_vmddr_selectors[] = { 0, 1, 2, 3, 4, 5, 6, 7, 9, 12 }; |
331 | static const struct linear_range mt6366_vmddr_ranges[] = { |
332 | REGULATOR_LINEAR_RANGE(600000, 0, 10, 10000), |
333 | REGULATOR_LINEAR_RANGE(700000, 0, 10, 10000), |
334 | REGULATOR_LINEAR_RANGE(800000, 0, 10, 10000), |
335 | REGULATOR_LINEAR_RANGE(900000, 0, 10, 10000), |
336 | REGULATOR_LINEAR_RANGE(1000000, 0, 10, 10000), |
337 | REGULATOR_LINEAR_RANGE(1100000, 0, 10, 10000), |
338 | REGULATOR_LINEAR_RANGE(1200000, 0, 10, 10000), |
339 | REGULATOR_LINEAR_RANGE(1300000, 0, 10, 10000), |
340 | REGULATOR_LINEAR_RANGE(1500000, 0, 10, 10000), |
341 | REGULATOR_LINEAR_RANGE(1800000, 0, 10, 10000), |
342 | }; |
343 | |
344 | static const unsigned int mt6366_vcn18_vm18_selectors[] = { |
345 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; |
346 | static const struct linear_range mt6366_vcn18_vm18_ranges[] = { |
347 | REGULATOR_LINEAR_RANGE(600000, 0, 10, 10000), |
348 | REGULATOR_LINEAR_RANGE(700000, 0, 10, 10000), |
349 | REGULATOR_LINEAR_RANGE(800000, 0, 10, 10000), |
350 | REGULATOR_LINEAR_RANGE(900000, 0, 10, 10000), |
351 | REGULATOR_LINEAR_RANGE(1000000, 0, 10, 10000), |
352 | REGULATOR_LINEAR_RANGE(1100000, 0, 10, 10000), |
353 | REGULATOR_LINEAR_RANGE(1200000, 0, 10, 10000), |
354 | REGULATOR_LINEAR_RANGE(1300000, 0, 10, 10000), |
355 | REGULATOR_LINEAR_RANGE(1400000, 0, 10, 10000), |
356 | REGULATOR_LINEAR_RANGE(1500000, 0, 10, 10000), |
357 | REGULATOR_LINEAR_RANGE(1600000, 0, 10, 10000), |
358 | REGULATOR_LINEAR_RANGE(1700000, 0, 10, 10000), |
359 | REGULATOR_LINEAR_RANGE(1800000, 0, 10, 10000), |
360 | REGULATOR_LINEAR_RANGE(1900000, 0, 10, 10000), |
361 | REGULATOR_LINEAR_RANGE(2000000, 0, 10, 10000), |
362 | REGULATOR_LINEAR_RANGE(2100000, 0, 10, 10000), |
363 | }; |
364 | |
365 | static unsigned int mt6358_map_mode(unsigned int mode) |
366 | { |
367 | return mode == MT6397_BUCK_MODE_AUTO ? |
368 | REGULATOR_MODE_NORMAL : REGULATOR_MODE_FAST; |
369 | } |
370 | |
371 | static int mt6358_get_buck_voltage_sel(struct regulator_dev *rdev) |
372 | { |
373 | const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc); |
374 | int ret, regval; |
375 | |
376 | ret = regmap_read(map: rdev->regmap, reg: info->da_vsel_reg, val: ®val); |
377 | if (ret != 0) { |
378 | dev_err(&rdev->dev, |
379 | "Failed to get mt6358 Buck %s vsel reg: %d\n" , |
380 | info->desc.name, ret); |
381 | return ret; |
382 | } |
383 | |
384 | ret = (regval & info->da_vsel_mask) >> (ffs(info->da_vsel_mask) - 1); |
385 | |
386 | return ret; |
387 | } |
388 | |
389 | static int mt6358_get_status(struct regulator_dev *rdev) |
390 | { |
391 | const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc); |
392 | int ret; |
393 | u32 regval; |
394 | |
395 | ret = regmap_read(map: rdev->regmap, reg: info->status_reg, val: ®val); |
396 | if (ret != 0) { |
397 | dev_info(&rdev->dev, "Failed to get enable reg: %d\n" , ret); |
398 | return ret; |
399 | } |
400 | |
401 | return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF; |
402 | } |
403 | |
404 | static int mt6358_regulator_set_mode(struct regulator_dev *rdev, |
405 | unsigned int mode) |
406 | { |
407 | const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc); |
408 | int val; |
409 | |
410 | switch (mode) { |
411 | case REGULATOR_MODE_FAST: |
412 | val = MT6397_BUCK_MODE_FORCE_PWM; |
413 | break; |
414 | case REGULATOR_MODE_NORMAL: |
415 | val = MT6397_BUCK_MODE_AUTO; |
416 | break; |
417 | default: |
418 | return -EINVAL; |
419 | } |
420 | |
421 | dev_dbg(&rdev->dev, "mt6358 buck set_mode %#x, %#x, %#x\n" , |
422 | info->modeset_reg, info->modeset_mask, val); |
423 | |
424 | val <<= ffs(info->modeset_mask) - 1; |
425 | |
426 | return regmap_update_bits(map: rdev->regmap, reg: info->modeset_reg, |
427 | mask: info->modeset_mask, val); |
428 | } |
429 | |
430 | static unsigned int mt6358_regulator_get_mode(struct regulator_dev *rdev) |
431 | { |
432 | const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc); |
433 | int ret, regval; |
434 | |
435 | ret = regmap_read(map: rdev->regmap, reg: info->modeset_reg, val: ®val); |
436 | if (ret != 0) { |
437 | dev_err(&rdev->dev, |
438 | "Failed to get mt6358 buck mode: %d\n" , ret); |
439 | return ret; |
440 | } |
441 | |
442 | switch ((regval & info->modeset_mask) >> (ffs(info->modeset_mask) - 1)) { |
443 | case MT6397_BUCK_MODE_AUTO: |
444 | return REGULATOR_MODE_NORMAL; |
445 | case MT6397_BUCK_MODE_FORCE_PWM: |
446 | return REGULATOR_MODE_FAST; |
447 | default: |
448 | return -EINVAL; |
449 | } |
450 | } |
451 | |
452 | static const struct regulator_ops mt6358_buck_ops = { |
453 | .list_voltage = regulator_list_voltage_linear, |
454 | .map_voltage = regulator_map_voltage_linear, |
455 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
456 | .get_voltage_sel = mt6358_get_buck_voltage_sel, |
457 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
458 | .enable = regulator_enable_regmap, |
459 | .disable = regulator_disable_regmap, |
460 | .is_enabled = regulator_is_enabled_regmap, |
461 | .get_status = mt6358_get_status, |
462 | .set_mode = mt6358_regulator_set_mode, |
463 | .get_mode = mt6358_regulator_get_mode, |
464 | }; |
465 | |
466 | static const struct regulator_ops mt6358_volt_range_ops = { |
467 | .list_voltage = regulator_list_voltage_linear, |
468 | .map_voltage = regulator_map_voltage_linear, |
469 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
470 | .get_voltage_sel = mt6358_get_buck_voltage_sel, |
471 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
472 | .enable = regulator_enable_regmap, |
473 | .disable = regulator_disable_regmap, |
474 | .is_enabled = regulator_is_enabled_regmap, |
475 | .get_status = mt6358_get_status, |
476 | }; |
477 | |
478 | static const struct regulator_ops mt6358_volt_table_ops = { |
479 | .list_voltage = regulator_list_voltage_pickable_linear_range, |
480 | .map_voltage = regulator_map_voltage_pickable_linear_range, |
481 | .set_voltage_sel = regulator_set_voltage_sel_pickable_regmap, |
482 | .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap, |
483 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
484 | .enable = regulator_enable_regmap, |
485 | .disable = regulator_disable_regmap, |
486 | .is_enabled = regulator_is_enabled_regmap, |
487 | .get_status = mt6358_get_status, |
488 | }; |
489 | |
490 | /* "Fixed" LDOs with output voltage calibration +0 ~ +10 mV */ |
491 | static const struct regulator_ops mt6358_volt_fixed_ops = { |
492 | .list_voltage = regulator_list_voltage_linear, |
493 | .map_voltage = regulator_map_voltage_linear, |
494 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
495 | .get_voltage_sel = mt6358_get_buck_voltage_sel, |
496 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
497 | .enable = regulator_enable_regmap, |
498 | .disable = regulator_disable_regmap, |
499 | .is_enabled = regulator_is_enabled_regmap, |
500 | .get_status = mt6358_get_status, |
501 | }; |
502 | |
503 | /* The array is indexed by id(MT6358_ID_XXX) */ |
504 | static const struct mt6358_regulator_info mt6358_regulators[] = { |
505 | MT6358_BUCK("buck_vdram1" , VDRAM1, "vsys-vdram1" , 500000, 2087500, 12500, |
506 | 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, MT6358_VDRAM1_ANA_CON0, 8), |
507 | MT6358_BUCK("buck_vcore" , VCORE, "vsys-vcore" , 500000, 1293750, 6250, |
508 | 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 1), |
509 | MT6358_BUCK("buck_vpa" , VPA, "vsys-vpa" , 500000, 3650000, 50000, |
510 | 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, MT6358_VPA_ANA_CON0, 3), |
511 | MT6358_BUCK("buck_vproc11" , VPROC11, "vsys-vproc11" , 500000, 1293750, 6250, |
512 | 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 1), |
513 | MT6358_BUCK("buck_vproc12" , VPROC12, "vsys-vproc12" , 500000, 1293750, 6250, |
514 | 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 2), |
515 | MT6358_BUCK("buck_vgpu" , VGPU, "vsys-vgpu" , 500000, 1293750, 6250, |
516 | 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 2), |
517 | MT6358_BUCK("buck_vs2" , VS2, "vsys-vs2" , 500000, 2087500, 12500, |
518 | 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, MT6358_VS2_ANA_CON0, 8), |
519 | MT6358_BUCK("buck_vmodem" , VMODEM, "vsys-vmodem" , 500000, 1293750, 6250, |
520 | 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, MT6358_VMODEM_ANA_CON0, 8), |
521 | MT6358_BUCK("buck_vs1" , VS1, "vsys-vs1" , 1000000, 2587500, 12500, |
522 | 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, MT6358_VS1_ANA_CON0, 8), |
523 | MT6358_REG_FIXED("ldo_vrf12" , VRF12, "vs2-ldo2" , MT6358_LDO_VRF12_CON0, 0, 1200000), |
524 | MT6358_REG_FIXED("ldo_vio18" , VIO18, "vs1-ldo1" , MT6358_LDO_VIO18_CON0, 0, 1800000), |
525 | MT6358_REG_FIXED("ldo_vcamio" , VCAMIO, "vs1-ldo1" , MT6358_LDO_VCAMIO_CON0, 0, 1800000), |
526 | MT6358_REG_FIXED("ldo_vcn18" , VCN18, "vs1-ldo1" , MT6358_LDO_VCN18_CON0, 0, 1800000), |
527 | MT6358_REG_FIXED("ldo_vfe28" , VFE28, "vsys-ldo1" , MT6358_LDO_VFE28_CON0, 0, 2800000), |
528 | MT6358_REG_FIXED("ldo_vcn28" , VCN28, "vsys-ldo1" , MT6358_LDO_VCN28_CON0, 0, 2800000), |
529 | MT6358_REG_FIXED("ldo_vxo22" , VXO22, "vsys-ldo1" , MT6358_LDO_VXO22_CON0, 0, 2200000), |
530 | MT6358_REG_FIXED("ldo_vaux18" , VAUX18, "vsys-ldo1" , MT6358_LDO_VAUX18_CON0, 0, 1800000), |
531 | MT6358_REG_FIXED("ldo_vbif28" , VBIF28, "vsys-ldo1" , MT6358_LDO_VBIF28_CON0, 0, 2800000), |
532 | MT6358_REG_FIXED("ldo_vio28" , VIO28, "vsys-ldo2" , MT6358_LDO_VIO28_CON0, 0, 2800000), |
533 | MT6358_REG_FIXED("ldo_va12" , VA12, "vs2-ldo2" , MT6358_LDO_VA12_CON0, 0, 1200000), |
534 | MT6358_REG_FIXED("ldo_vrf18" , VRF18, "vs1-ldo1" , MT6358_LDO_VRF18_CON0, 0, 1800000), |
535 | MT6358_REG_FIXED("ldo_vaud28" , VAUD28, "vsys-ldo1" , MT6358_LDO_VAUD28_CON0, 0, 2800000), |
536 | MT6358_LDO("ldo_vdram2" , VDRAM2, "vs2-ldo1" , vdram2, |
537 | MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0xf), |
538 | MT6358_LDO("ldo_vsim1" , VSIM1, "vsys-ldo1" , vsim, |
539 | MT6358_LDO_VSIM1_CON0, 0, MT6358_VSIM1_ANA_CON0, 0xf00), |
540 | MT6358_LDO("ldo_vibr" , VIBR, "vsys-ldo3" , vibr, |
541 | MT6358_LDO_VIBR_CON0, 0, MT6358_VIBR_ANA_CON0, 0xf00), |
542 | MT6358_LDO("ldo_vusb" , VUSB, "vsys-ldo1" , vusb, |
543 | MT6358_LDO_VUSB_CON0_0, 0, MT6358_VUSB_ANA_CON0, 0x700), |
544 | MT6358_LDO("ldo_vcamd" , VCAMD, "vs2-ldo4" , vcamd, |
545 | MT6358_LDO_VCAMD_CON0, 0, MT6358_VCAMD_ANA_CON0, 0xf00), |
546 | MT6358_LDO("ldo_vefuse" , VEFUSE, "vs1-ldo1" , vefuse, |
547 | MT6358_LDO_VEFUSE_CON0, 0, MT6358_VEFUSE_ANA_CON0, 0xf00), |
548 | MT6358_LDO("ldo_vmch" , VMCH, "vsys-ldo2" , vmch_vemc, |
549 | MT6358_LDO_VMCH_CON0, 0, MT6358_VMCH_ANA_CON0, 0x700), |
550 | MT6358_LDO("ldo_vcama1" , VCAMA1, "vsys-ldo3" , vcama, |
551 | MT6358_LDO_VCAMA1_CON0, 0, MT6358_VCAMA1_ANA_CON0, 0xf00), |
552 | MT6358_LDO("ldo_vemc" , VEMC, "vsys-ldo2" , vmch_vemc, |
553 | MT6358_LDO_VEMC_CON0, 0, MT6358_VEMC_ANA_CON0, 0x700), |
554 | MT6358_LDO("ldo_vcn33" , VCN33, "vsys-ldo3" , vcn33, |
555 | MT6358_LDO_VCN33_CON0_0, 0, MT6358_VCN33_ANA_CON0, 0x300), |
556 | MT6358_LDO("ldo_vcama2" , VCAMA2, "vsys-ldo3" , vcama, |
557 | MT6358_LDO_VCAMA2_CON0, 0, MT6358_VCAMA2_ANA_CON0, 0xf00), |
558 | MT6358_LDO("ldo_vmc" , VMC, "vsys-ldo2" , vmc, |
559 | MT6358_LDO_VMC_CON0, 0, MT6358_VMC_ANA_CON0, 0xf00), |
560 | MT6358_LDO("ldo_vldo28" , VLDO28, "vsys-ldo2" , vldo28, |
561 | MT6358_LDO_VLDO28_CON0_0, 0, |
562 | MT6358_VLDO28_ANA_CON0, 0x300), |
563 | MT6358_LDO("ldo_vsim2" , VSIM2, "vsys-ldo2" , vsim, |
564 | MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00), |
565 | MT6358_LDO1("ldo_vsram_proc11" , VSRAM_PROC11, "vs2-ldo3" , 500000, 1293750, 6250, |
566 | MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON0, 0x7f), |
567 | MT6358_LDO1("ldo_vsram_others" , VSRAM_OTHERS, "vs2-ldo3" , 500000, 1293750, 6250, |
568 | MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON2, 0x7f), |
569 | MT6358_LDO1("ldo_vsram_gpu" , VSRAM_GPU, "vs2-ldo3" , 500000, 1293750, 6250, |
570 | MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON3, 0x7f), |
571 | MT6358_LDO1("ldo_vsram_proc12" , VSRAM_PROC12, "vs2-ldo3" , 500000, 1293750, 6250, |
572 | MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON1, 0x7f), |
573 | }; |
574 | |
575 | /* The array is indexed by id(MT6366_ID_XXX) */ |
576 | static const struct mt6358_regulator_info mt6366_regulators[] = { |
577 | MT6366_BUCK("vdram1" , VDRAM1, 500000, 2087500, 12500, |
578 | 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, MT6358_VDRAM1_ANA_CON0, 8), |
579 | MT6366_BUCK("vcore" , VCORE, 500000, 1293750, 6250, |
580 | 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 1), |
581 | MT6366_BUCK("vpa" , VPA, 500000, 3650000, 50000, |
582 | 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, MT6358_VPA_ANA_CON0, 3), |
583 | MT6366_BUCK("vproc11" , VPROC11, 500000, 1293750, 6250, |
584 | 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 1), |
585 | MT6366_BUCK("vproc12" , VPROC12, 500000, 1293750, 6250, |
586 | 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 2), |
587 | MT6366_BUCK("vgpu" , VGPU, 500000, 1293750, 6250, |
588 | 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 2), |
589 | MT6366_BUCK("vs2" , VS2, 500000, 2087500, 12500, |
590 | 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, MT6358_VS2_ANA_CON0, 8), |
591 | MT6366_BUCK("vmodem" , VMODEM, 500000, 1293750, 6250, |
592 | 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, MT6358_VMODEM_ANA_CON0, 8), |
593 | MT6366_BUCK("vs1" , VS1, 1000000, 2587500, 12500, |
594 | 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, MT6358_VS1_ANA_CON0, 8), |
595 | MT6366_REG_FIXED("vrf12" , VRF12, "vs2-ldo2" , MT6358_LDO_VRF12_CON0, 0, 1200000), |
596 | MT6366_REG_FIXED("vio18" , VIO18, "vs1-ldo1" , MT6358_LDO_VIO18_CON0, 0, 1800000), |
597 | MT6366_REG_FIXED("vfe28" , VFE28, "vsys-ldo1" , MT6358_LDO_VFE28_CON0, 0, 2800000), |
598 | MT6366_REG_FIXED("vcn28" , VCN28, "vsys-ldo1" , MT6358_LDO_VCN28_CON0, 0, 2800000), |
599 | MT6366_REG_FIXED("vxo22" , VXO22, "vsys-ldo1" , MT6358_LDO_VXO22_CON0, 0, 2200000), |
600 | MT6366_REG_FIXED("vaux18" , VAUX18, "vsys-ldo1" , MT6358_LDO_VAUX18_CON0, 0, 1800000), |
601 | MT6366_REG_FIXED("vbif28" , VBIF28, "vsys-ldo1" , MT6358_LDO_VBIF28_CON0, 0, 2800000), |
602 | MT6366_REG_FIXED("vio28" , VIO28, "vsys-ldo2" , MT6358_LDO_VIO28_CON0, 0, 2800000), |
603 | MT6366_REG_FIXED("va12" , VA12, "vs2-ldo2" , MT6358_LDO_VA12_CON0, 0, 1200000), |
604 | MT6366_REG_FIXED("vrf18" , VRF18, "vs1-ldo1" , MT6358_LDO_VRF18_CON0, 0, 1800000), |
605 | MT6366_REG_FIXED("vaud28" , VAUD28, "vsys-ldo1" , MT6358_LDO_VAUD28_CON0, 0, 2800000), |
606 | MT6366_LDO("vdram2" , VDRAM2, vdram2, "vs2-ldo1" , |
607 | MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0x10), |
608 | MT6366_LDO("vsim1" , VSIM1, vsim, "vsys-ldo1" , |
609 | MT6358_LDO_VSIM1_CON0, 0, MT6358_VSIM1_ANA_CON0, 0xf00), |
610 | MT6366_LDO("vibr" , VIBR, vibr, "vsys-ldo3" , |
611 | MT6358_LDO_VIBR_CON0, 0, MT6358_VIBR_ANA_CON0, 0xf00), |
612 | MT6366_LDO("vusb" , VUSB, vusb, "vsys-ldo1" , |
613 | MT6358_LDO_VUSB_CON0_0, 0, MT6358_VUSB_ANA_CON0, 0x700), |
614 | MT6366_LDO("vefuse" , VEFUSE, vefuse, "vs1-ldo1" , |
615 | MT6358_LDO_VEFUSE_CON0, 0, MT6358_VEFUSE_ANA_CON0, 0xf00), |
616 | MT6366_LDO("vmch" , VMCH, vmch_vemc, "vsys-ldo2" , |
617 | MT6358_LDO_VMCH_CON0, 0, MT6358_VMCH_ANA_CON0, 0x700), |
618 | MT6366_LDO("vemc" , VEMC, vmch_vemc, "vsys-ldo3" , |
619 | MT6358_LDO_VEMC_CON0, 0, MT6358_VEMC_ANA_CON0, 0x700), |
620 | MT6366_LDO("vcn33" , VCN33, vcn33, "vsys-ldo3" , |
621 | MT6358_LDO_VCN33_CON0_0, 0, MT6358_VCN33_ANA_CON0, 0x300), |
622 | MT6366_LDO("vmc" , VMC, vmc, "vsys-ldo2" , |
623 | MT6358_LDO_VMC_CON0, 0, MT6358_VMC_ANA_CON0, 0xf00), |
624 | MT6366_LDO("vsim2" , VSIM2, vsim, "vsys-ldo2" , |
625 | MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00), |
626 | MT6366_LDO("vcn18" , VCN18, mt6366_vcn18_vm18, "vs1-ldo1" , |
627 | MT6358_LDO_VCN18_CON0, 0, MT6358_VCN18_ANA_CON0, 0xf00), |
628 | MT6366_LDO("vm18" , VM18, mt6366_vcn18_vm18, "vs1-ldo1" , |
629 | MT6358_LDO_VM18_CON0, 0, MT6358_VM18_ANA_CON0, 0xf00), |
630 | MT6366_LDO("vmddr" , VMDDR, mt6366_vmddr, "vs2-ldo1" , |
631 | MT6358_LDO_VMDDR_CON0, 0, MT6358_VMDDR_ANA_CON0, 0xf00), |
632 | MT6366_LDO1("vsram-proc11" , VSRAM_PROC11, "vs2-ldo3" , 500000, 1293750, 6250, |
633 | MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON0, 0x7f), |
634 | MT6366_LDO1("vsram-others" , VSRAM_OTHERS, "vs2-ldo3" , 500000, 1293750, 6250, |
635 | MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON2, 0x7f), |
636 | MT6366_LDO1("vsram-gpu" , VSRAM_GPU, "vs2-ldo3" , 500000, 1293750, 6250, |
637 | MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON3, 0x7f), |
638 | MT6366_LDO1("vsram-proc12" , VSRAM_PROC12, "vs2-ldo3" , 500000, 1293750, 6250, |
639 | MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON1, 0x7f), |
640 | MT6366_LDO1("vsram-core" , VSRAM_CORE, "vs2-ldo3" , 500000, 1293750, 6250, |
641 | MT6358_LDO_VSRAM_CORE_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON5, 0x7f), |
642 | }; |
643 | |
644 | static int mt6358_sync_vcn33_setting(struct device *dev) |
645 | { |
646 | struct mt6397_chip *mt6397 = dev_get_drvdata(dev: dev->parent); |
647 | unsigned int val; |
648 | int ret; |
649 | |
650 | /* |
651 | * VCN33_WIFI and VCN33_BT are two separate enable bits for the same |
652 | * regulator. They share the same voltage setting and output pin. |
653 | * Instead of having two potentially conflicting regulators, just have |
654 | * one VCN33 regulator. Sync the two enable bits and only use one in |
655 | * the regulator device. |
656 | */ |
657 | ret = regmap_read(map: mt6397->regmap, MT6358_LDO_VCN33_CON0_1, val: &val); |
658 | if (ret) { |
659 | dev_err(dev, "Failed to read VCN33_WIFI setting\n" ); |
660 | return ret; |
661 | } |
662 | |
663 | if (!(val & BIT(0))) |
664 | return 0; |
665 | |
666 | /* Sync VCN33_WIFI enable status to VCN33_BT */ |
667 | ret = regmap_update_bits(map: mt6397->regmap, MT6358_LDO_VCN33_CON0_0, BIT(0), BIT(0)); |
668 | if (ret) { |
669 | dev_err(dev, "Failed to sync VCN33_WIFI setting to VCN33_BT\n" ); |
670 | return ret; |
671 | } |
672 | |
673 | /* Disable VCN33_WIFI */ |
674 | ret = regmap_update_bits(map: mt6397->regmap, MT6358_LDO_VCN33_CON0_1, BIT(0), val: 0); |
675 | if (ret) { |
676 | dev_err(dev, "Failed to disable VCN33_WIFI\n" ); |
677 | return ret; |
678 | } |
679 | |
680 | return 0; |
681 | } |
682 | |
683 | static int mt6358_regulator_probe(struct platform_device *pdev) |
684 | { |
685 | struct mt6397_chip *mt6397 = dev_get_drvdata(dev: pdev->dev.parent); |
686 | struct regulator_config config = {}; |
687 | struct regulator_dev *rdev; |
688 | const struct mt6358_regulator_info *mt6358_info; |
689 | int i, max_regulator, ret; |
690 | |
691 | switch (mt6397->chip_id) { |
692 | case MT6358_CHIP_ID: |
693 | max_regulator = MT6358_MAX_REGULATOR; |
694 | mt6358_info = mt6358_regulators; |
695 | break; |
696 | case MT6366_CHIP_ID: |
697 | max_regulator = MT6366_MAX_REGULATOR; |
698 | mt6358_info = mt6366_regulators; |
699 | break; |
700 | default: |
701 | dev_err(&pdev->dev, "unsupported chip ID: %d\n" , mt6397->chip_id); |
702 | return -EINVAL; |
703 | } |
704 | |
705 | ret = mt6358_sync_vcn33_setting(dev: &pdev->dev); |
706 | if (ret) |
707 | return ret; |
708 | |
709 | for (i = 0; i < max_regulator; i++) { |
710 | config.dev = &pdev->dev; |
711 | config.regmap = mt6397->regmap; |
712 | |
713 | rdev = devm_regulator_register(dev: &pdev->dev, |
714 | regulator_desc: &mt6358_info[i].desc, |
715 | config: &config); |
716 | if (IS_ERR(ptr: rdev)) { |
717 | dev_err(&pdev->dev, "failed to register %s\n" , |
718 | mt6358_info[i].desc.name); |
719 | return PTR_ERR(ptr: rdev); |
720 | } |
721 | } |
722 | |
723 | return 0; |
724 | } |
725 | |
726 | static const struct platform_device_id mt6358_platform_ids[] = { |
727 | {"mt6358-regulator" , 0}, |
728 | { /* sentinel */ }, |
729 | }; |
730 | MODULE_DEVICE_TABLE(platform, mt6358_platform_ids); |
731 | |
732 | static struct platform_driver mt6358_regulator_driver = { |
733 | .driver = { |
734 | .name = "mt6358-regulator" , |
735 | .probe_type = PROBE_PREFER_ASYNCHRONOUS, |
736 | }, |
737 | .probe = mt6358_regulator_probe, |
738 | .id_table = mt6358_platform_ids, |
739 | }; |
740 | |
741 | module_platform_driver(mt6358_regulator_driver); |
742 | |
743 | MODULE_AUTHOR("Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>" ); |
744 | MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6358 PMIC" ); |
745 | MODULE_LICENSE("GPL" ); |
746 | |