]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/regulator/mt6397-regulator.c
drivers/base: use %*pb[l] to print bitmaps including cpumasks and nodemasks
[karo-tx-linux.git] / drivers / regulator / mt6397-regulator.c
1 /*
2  * Copyright (c) 2014 MediaTek Inc.
3  * Author: Flora Fu <flora.fu@mediatek.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14
15 #include <linux/module.h>
16 #include <linux/of.h>
17 #include <linux/platform_device.h>
18 #include <linux/regmap.h>
19 #include <linux/mfd/mt6397/core.h>
20 #include <linux/mfd/mt6397/registers.h>
21 #include <linux/regulator/driver.h>
22 #include <linux/regulator/machine.h>
23 #include <linux/regulator/mt6397-regulator.h>
24 #include <linux/regulator/of_regulator.h>
25
26 /*
27  * MT6397 regulators' information
28  *
29  * @desc: standard fields of regulator description.
30  * @qi: Mask for query enable signal status of regulators
31  * @vselon_reg: Register sections for hardware control mode of bucks
32  * @vselctrl_reg: Register for controlling the buck control mode.
33  * @vselctrl_mask: Mask for query buck's voltage control mode.
34  */
35 struct mt6397_regulator_info {
36         struct regulator_desc desc;
37         u32 qi;
38         u32 vselon_reg;
39         u32 vselctrl_reg;
40         u32 vselctrl_mask;
41 };
42
43 #define MT6397_BUCK(match, vreg, min, max, step, volt_ranges, enreg,    \
44                 vosel, vosel_mask, voselon, vosel_ctrl)                 \
45 [MT6397_ID_##vreg] = {                                                  \
46         .desc = {                                                       \
47                 .name = #vreg,                                          \
48                 .of_match = of_match_ptr(match),                        \
49                 .ops = &mt6397_volt_range_ops,                          \
50                 .type = REGULATOR_VOLTAGE,                              \
51                 .id = MT6397_ID_##vreg,                                 \
52                 .owner = THIS_MODULE,                                   \
53                 .n_voltages = (max - min)/step + 1,                     \
54                 .linear_ranges = volt_ranges,                           \
55                 .n_linear_ranges = ARRAY_SIZE(volt_ranges),             \
56                 .vsel_reg = vosel,                                      \
57                 .vsel_mask = vosel_mask,                                \
58                 .enable_reg = enreg,                                    \
59                 .enable_mask = BIT(0),                                  \
60         },                                                              \
61         .qi = BIT(13),                                                  \
62         .vselon_reg = voselon,                                          \
63         .vselctrl_reg = vosel_ctrl,                                     \
64         .vselctrl_mask = BIT(1),                                        \
65 }
66
67 #define MT6397_LDO(match, vreg, ldo_volt_table, enreg, enbit, vosel,    \
68                 vosel_mask)                                             \
69 [MT6397_ID_##vreg] = {                                                  \
70         .desc = {                                                       \
71                 .name = #vreg,                                          \
72                 .of_match = of_match_ptr(match),                        \
73                 .ops = &mt6397_volt_table_ops,                          \
74                 .type = REGULATOR_VOLTAGE,                              \
75                 .id = MT6397_ID_##vreg,                                 \
76                 .owner = THIS_MODULE,                                   \
77                 .n_voltages = ARRAY_SIZE(ldo_volt_table),               \
78                 .volt_table = ldo_volt_table,                           \
79                 .vsel_reg = vosel,                                      \
80                 .vsel_mask = vosel_mask,                                \
81                 .enable_reg = enreg,                                    \
82                 .enable_mask = BIT(enbit),                              \
83         },                                                              \
84         .qi = BIT(15),                                                  \
85 }
86
87 #define MT6397_REG_FIXED(match, vreg, enreg, enbit, volt)               \
88 [MT6397_ID_##vreg] = {                                                  \
89         .desc = {                                                       \
90                 .name = #vreg,                                          \
91                 .of_match = of_match_ptr(match),                        \
92                 .ops = &mt6397_volt_fixed_ops,                          \
93                 .type = REGULATOR_VOLTAGE,                              \
94                 .id = MT6397_ID_##vreg,                                 \
95                 .owner = THIS_MODULE,                                   \
96                 .n_voltages = 1,                                        \
97                 .enable_reg = enreg,                                    \
98                 .enable_mask = BIT(enbit),                              \
99                 .min_uV = volt,                                         \
100         },                                                              \
101         .qi = BIT(15),                                                  \
102 }
103
104 static const struct regulator_linear_range buck_volt_range1[] = {
105         REGULATOR_LINEAR_RANGE(700000, 0, 0x7f, 6250),
106 };
107
108 static const struct regulator_linear_range buck_volt_range2[] = {
109         REGULATOR_LINEAR_RANGE(800000, 0, 0x7f, 6250),
110 };
111
112 static const struct regulator_linear_range buck_volt_range3[] = {
113         REGULATOR_LINEAR_RANGE(1500000, 0, 0x1f, 20000),
114 };
115
116 static const u32 ldo_volt_table1[] = {
117         1500000, 1800000, 2500000, 2800000,
118 };
119
120 static const u32 ldo_volt_table2[] = {
121         1800000, 3300000,
122 };
123
124 static const u32 ldo_volt_table3[] = {
125         3000000, 3300000,
126 };
127
128 static const u32 ldo_volt_table4[] = {
129         1220000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000,
130 };
131
132 static const u32 ldo_volt_table5[] = {
133         1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000,
134 };
135
136 static const u32 ldo_volt_table5_v2[] = {
137         1200000, 1000000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000,
138 };
139
140 static const u32 ldo_volt_table6[] = {
141         1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 2000000,
142 };
143
144 static const u32 ldo_volt_table7[] = {
145         1300000, 1500000, 1800000, 2000000, 2500000, 2800000, 3000000, 3300000,
146 };
147
148 static int mt6397_get_status(struct regulator_dev *rdev)
149 {
150         int ret;
151         u32 regval;
152         struct mt6397_regulator_info *info = rdev_get_drvdata(rdev);
153
154         ret = regmap_read(rdev->regmap, info->desc.enable_reg, &regval);
155         if (ret != 0) {
156                 dev_err(&rdev->dev, "Failed to get enable reg: %d\n", ret);
157                 return ret;
158         }
159
160         return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF;
161 }
162
163 static struct regulator_ops mt6397_volt_range_ops = {
164         .list_voltage = regulator_list_voltage_linear_range,
165         .map_voltage = regulator_map_voltage_linear_range,
166         .set_voltage_sel = regulator_set_voltage_sel_regmap,
167         .get_voltage_sel = regulator_get_voltage_sel_regmap,
168         .set_voltage_time_sel = regulator_set_voltage_time_sel,
169         .enable = regulator_enable_regmap,
170         .disable = regulator_disable_regmap,
171         .is_enabled = regulator_is_enabled_regmap,
172         .get_status = mt6397_get_status,
173 };
174
175 static struct regulator_ops mt6397_volt_table_ops = {
176         .list_voltage = regulator_list_voltage_table,
177         .map_voltage = regulator_map_voltage_iterate,
178         .set_voltage_sel = regulator_set_voltage_sel_regmap,
179         .get_voltage_sel = regulator_get_voltage_sel_regmap,
180         .set_voltage_time_sel = regulator_set_voltage_time_sel,
181         .enable = regulator_enable_regmap,
182         .disable = regulator_disable_regmap,
183         .is_enabled = regulator_is_enabled_regmap,
184         .get_status = mt6397_get_status,
185 };
186
187 static struct regulator_ops mt6397_volt_fixed_ops = {
188         .list_voltage = regulator_list_voltage_linear,
189         .enable = regulator_enable_regmap,
190         .disable = regulator_disable_regmap,
191         .is_enabled = regulator_is_enabled_regmap,
192         .get_status = mt6397_get_status,
193 };
194
195 /* The array is indexed by id(MT6397_ID_XXX) */
196 static struct mt6397_regulator_info mt6397_regulators[] = {
197         MT6397_BUCK("buck_vpca15", VPCA15, 700000, 1493750, 6250,
198                 buck_volt_range1, MT6397_VCA15_CON7, MT6397_VCA15_CON9, 0x7f,
199                 MT6397_VCA15_CON10, MT6397_VCA15_CON5),
200         MT6397_BUCK("buck_vpca7", VPCA7, 700000, 1493750, 6250,
201                 buck_volt_range1, MT6397_VPCA7_CON7, MT6397_VPCA7_CON9, 0x7f,
202                 MT6397_VPCA7_CON10, MT6397_VPCA7_CON5),
203         MT6397_BUCK("buck_vsramca15", VSRAMCA15, 700000, 1493750, 6250,
204                 buck_volt_range1, MT6397_VSRMCA15_CON7, MT6397_VSRMCA15_CON9,
205                 0x7f, MT6397_VSRMCA15_CON10, MT6397_VSRMCA15_CON5),
206         MT6397_BUCK("buck_vsramca7", VSRAMCA7, 700000, 1493750, 6250,
207                 buck_volt_range1, MT6397_VSRMCA7_CON7, MT6397_VSRMCA7_CON9,
208                 0x7f, MT6397_VSRMCA7_CON10, MT6397_VSRMCA7_CON5),
209         MT6397_BUCK("buck_vcore", VCORE, 700000, 1493750, 6250,
210                 buck_volt_range1, MT6397_VCORE_CON7, MT6397_VCORE_CON9, 0x7f,
211                 MT6397_VCORE_CON10, MT6397_VCORE_CON5),
212         MT6397_BUCK("buck_vgpu", VGPU, 700000, 1493750, 6250, buck_volt_range1,
213                 MT6397_VGPU_CON7, MT6397_VGPU_CON9, 0x7f,
214                 MT6397_VGPU_CON10, MT6397_VGPU_CON5),
215         MT6397_BUCK("buck_vdrm", VDRM, 800000, 1593750, 6250, buck_volt_range2,
216                 MT6397_VDRM_CON7, MT6397_VDRM_CON9, 0x7f,
217                 MT6397_VDRM_CON10, MT6397_VDRM_CON5),
218         MT6397_BUCK("buck_vio18", VIO18, 1500000, 2120000, 20000,
219                 buck_volt_range3, MT6397_VIO18_CON7, MT6397_VIO18_CON9, 0x1f,
220                 MT6397_VIO18_CON10, MT6397_VIO18_CON5),
221         MT6397_REG_FIXED("ldo_vtcxo", VTCXO, MT6397_ANALDO_CON0, 10, 2800000),
222         MT6397_REG_FIXED("ldo_va28", VA28, MT6397_ANALDO_CON1, 14, 2800000),
223         MT6397_LDO("ldo_vcama", VCAMA, ldo_volt_table1,
224                 MT6397_ANALDO_CON2, 15, MT6397_ANALDO_CON6, 0xC0),
225         MT6397_REG_FIXED("ldo_vio28", VIO28, MT6397_DIGLDO_CON0, 14, 2800000),
226         MT6397_REG_FIXED("ldo_vusb", VUSB, MT6397_DIGLDO_CON1, 14, 3300000),
227         MT6397_LDO("ldo_vmc", VMC, ldo_volt_table2,
228                 MT6397_DIGLDO_CON2, 12, MT6397_DIGLDO_CON29, 0x10),
229         MT6397_LDO("ldo_vmch", VMCH, ldo_volt_table3,
230                 MT6397_DIGLDO_CON3, 14, MT6397_DIGLDO_CON17, 0x80),
231         MT6397_LDO("ldo_vemc3v3", VEMC3V3, ldo_volt_table3,
232                 MT6397_DIGLDO_CON4, 14, MT6397_DIGLDO_CON18, 0x10),
233         MT6397_LDO("ldo_vgp1", VGP1, ldo_volt_table4,
234                 MT6397_DIGLDO_CON5, 15, MT6397_DIGLDO_CON19, 0xE0),
235         MT6397_LDO("ldo_vgp2", VGP2, ldo_volt_table5,
236                 MT6397_DIGLDO_CON6, 15, MT6397_DIGLDO_CON20, 0xE0),
237         MT6397_LDO("ldo_vgp3", VGP3, ldo_volt_table5,
238                 MT6397_DIGLDO_CON7, 15, MT6397_DIGLDO_CON21, 0xE0),
239         MT6397_LDO("ldo_vgp4", VGP4, ldo_volt_table5,
240                 MT6397_DIGLDO_CON8, 15, MT6397_DIGLDO_CON22, 0xE0),
241         MT6397_LDO("ldo_vgp5", VGP5, ldo_volt_table6,
242                 MT6397_DIGLDO_CON9, 15, MT6397_DIGLDO_CON23, 0xE0),
243         MT6397_LDO("ldo_vgp6", VGP6, ldo_volt_table5,
244                 MT6397_DIGLDO_CON10, 15, MT6397_DIGLDO_CON33, 0xE0),
245         MT6397_LDO("ldo_vibr", VIBR, ldo_volt_table7,
246                 MT6397_DIGLDO_CON24, 15, MT6397_DIGLDO_CON25, 0xE00),
247 };
248
249 static int mt6397_set_buck_vosel_reg(struct platform_device *pdev)
250 {
251         struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);
252         int i;
253         u32 regval;
254
255         for (i = 0; i < MT6397_MAX_REGULATOR; i++) {
256                 if (mt6397_regulators[i].vselctrl_reg) {
257                         if (regmap_read(mt6397->regmap,
258                                 mt6397_regulators[i].vselctrl_reg,
259                                 &regval) < 0) {
260                                 dev_err(&pdev->dev,
261                                         "Failed to read buck ctrl\n");
262                                 return -EIO;
263                         }
264
265                         if (regval & mt6397_regulators[i].vselctrl_mask) {
266                                 mt6397_regulators[i].desc.vsel_reg =
267                                 mt6397_regulators[i].vselon_reg;
268                         }
269                 }
270         }
271
272         return 0;
273 }
274
275 static int mt6397_regulator_probe(struct platform_device *pdev)
276 {
277         struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);
278         struct regulator_config config = {};
279         struct regulator_dev *rdev;
280         int i;
281         u32 reg_value, version;
282
283         /* Query buck controller to select activated voltage register part */
284         if (mt6397_set_buck_vosel_reg(pdev))
285                 return -EIO;
286
287         /* Read PMIC chip revision to update constraints and voltage table */
288         if (regmap_read(mt6397->regmap, MT6397_CID, &reg_value) < 0) {
289                 dev_err(&pdev->dev, "Failed to read Chip ID\n");
290                 return -EIO;
291         }
292         dev_info(&pdev->dev, "Chip ID = 0x%x\n", reg_value);
293
294         version = (reg_value & 0xFF);
295         switch (version) {
296         case MT6397_REGULATOR_ID91:
297                 mt6397_regulators[MT6397_ID_VGP2].desc.volt_table =
298                 ldo_volt_table5_v2;
299                 break;
300         default:
301                 break;
302         }
303
304         for (i = 0; i < MT6397_MAX_REGULATOR; i++) {
305                 config.dev = &pdev->dev;
306                 config.driver_data = &mt6397_regulators[i];
307                 config.regmap = mt6397->regmap;
308                 rdev = devm_regulator_register(&pdev->dev,
309                                 &mt6397_regulators[i].desc, &config);
310                 if (IS_ERR(rdev)) {
311                         dev_err(&pdev->dev, "failed to register %s\n",
312                                 mt6397_regulators[i].desc.name);
313                         return PTR_ERR(rdev);
314                 }
315         }
316
317         return 0;
318 }
319
320 static struct platform_driver mt6397_regulator_driver = {
321         .driver = {
322                 .name = "mt6397-regulator",
323         },
324         .probe = mt6397_regulator_probe,
325 };
326
327 module_platform_driver(mt6397_regulator_driver);
328
329 MODULE_AUTHOR("Flora Fu <flora.fu@mediatek.com>");
330 MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6397 PMIC");
331 MODULE_LICENSE("GPL");
332 MODULE_ALIAS("platform:mt6397-regulator");