Merge tag 'xtensa-20230523' of https://github.com/jcmvbkbc/linux-xtensa
[platform/kernel/linux-starfive.git] / drivers / regulator / max77650-regulator.c
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Copyright (C) 2018 BayLibre SAS
4 // Author: Bartosz Golaszewski <bgolaszewski@baylibre.com>
5 //
6 // Regulator driver for MAXIM 77650/77651 charger/power-supply.
7
8 #include <linux/of.h>
9 #include <linux/mfd/max77650.h>
10 #include <linux/module.h>
11 #include <linux/platform_device.h>
12 #include <linux/regmap.h>
13 #include <linux/regulator/driver.h>
14
15 #define MAX77650_REGULATOR_EN_CTRL_MASK         GENMASK(3, 0)
16 #define MAX77650_REGULATOR_EN_CTRL_BITS(_reg) \
17                 ((_reg) & MAX77650_REGULATOR_EN_CTRL_MASK)
18 #define MAX77650_REGULATOR_ENABLED              GENMASK(2, 1)
19 #define MAX77650_REGULATOR_DISABLED             BIT(2)
20
21 #define MAX77650_REGULATOR_V_LDO_MASK           GENMASK(6, 0)
22 #define MAX77650_REGULATOR_V_SBB_MASK           GENMASK(5, 0)
23 #define MAX77651_REGULATOR_V_SBB1_MASK          GENMASK(5, 2)
24 #define MAX77651_REGULATOR_V_SBB1_RANGE_MASK    GENMASK(1, 0)
25
26 #define MAX77650_REGULATOR_AD_MASK              BIT(3)
27 #define MAX77650_REGULATOR_AD_DISABLED          0x00
28 #define MAX77650_REGULATOR_AD_ENABLED           BIT(3)
29
30 #define MAX77650_REGULATOR_CURR_LIM_MASK        GENMASK(7, 6)
31
32 enum {
33         MAX77650_REGULATOR_ID_LDO = 0,
34         MAX77650_REGULATOR_ID_SBB0,
35         MAX77650_REGULATOR_ID_SBB1,
36         MAX77650_REGULATOR_ID_SBB2,
37         MAX77650_REGULATOR_NUM_REGULATORS,
38 };
39
40 struct max77650_regulator_desc {
41         struct regulator_desc desc;
42         unsigned int regA;
43         unsigned int regB;
44 };
45
46 static struct max77650_regulator_desc max77651_SBB1_desc;
47
48 static const unsigned int max77651_sbb1_volt_range_sel[] = {
49         0x0, 0x1, 0x2, 0x3
50 };
51
52 static const struct linear_range max77651_sbb1_volt_ranges[] = {
53         /* range index 0 */
54         REGULATOR_LINEAR_RANGE(2400000, 0x00, 0x0f, 50000),
55         /* range index 1 */
56         REGULATOR_LINEAR_RANGE(3200000, 0x00, 0x0f, 50000),
57         /* range index 2 */
58         REGULATOR_LINEAR_RANGE(4000000, 0x00, 0x0f, 50000),
59         /* range index 3 */
60         REGULATOR_LINEAR_RANGE(4800000, 0x00, 0x09, 50000),
61 };
62
63 static const unsigned int max77650_current_limit_table[] = {
64         1000000, 866000, 707000, 500000,
65 };
66
67 static int max77650_regulator_is_enabled(struct regulator_dev *rdev)
68 {
69         struct max77650_regulator_desc *rdesc;
70         struct regmap *map;
71         int val, rv, en;
72
73         rdesc = rdev_get_drvdata(rdev);
74         map = rdev_get_regmap(rdev);
75
76         rv = regmap_read(map, rdesc->regB, &val);
77         if (rv)
78                 return rv;
79
80         en = MAX77650_REGULATOR_EN_CTRL_BITS(val);
81
82         return en != MAX77650_REGULATOR_DISABLED;
83 }
84
85 static int max77650_regulator_enable(struct regulator_dev *rdev)
86 {
87         struct max77650_regulator_desc *rdesc;
88         struct regmap *map;
89
90         rdesc = rdev_get_drvdata(rdev);
91         map = rdev_get_regmap(rdev);
92
93         return regmap_update_bits(map, rdesc->regB,
94                                   MAX77650_REGULATOR_EN_CTRL_MASK,
95                                   MAX77650_REGULATOR_ENABLED);
96 }
97
98 static int max77650_regulator_disable(struct regulator_dev *rdev)
99 {
100         struct max77650_regulator_desc *rdesc;
101         struct regmap *map;
102
103         rdesc = rdev_get_drvdata(rdev);
104         map = rdev_get_regmap(rdev);
105
106         return regmap_update_bits(map, rdesc->regB,
107                                   MAX77650_REGULATOR_EN_CTRL_MASK,
108                                   MAX77650_REGULATOR_DISABLED);
109 }
110
111 static const struct regulator_ops max77650_regulator_LDO_ops = {
112         .is_enabled             = max77650_regulator_is_enabled,
113         .enable                 = max77650_regulator_enable,
114         .disable                = max77650_regulator_disable,
115         .list_voltage           = regulator_list_voltage_linear,
116         .map_voltage            = regulator_map_voltage_linear,
117         .get_voltage_sel        = regulator_get_voltage_sel_regmap,
118         .set_voltage_sel        = regulator_set_voltage_sel_regmap,
119         .set_active_discharge   = regulator_set_active_discharge_regmap,
120 };
121
122 static const struct regulator_ops max77650_regulator_SBB_ops = {
123         .is_enabled             = max77650_regulator_is_enabled,
124         .enable                 = max77650_regulator_enable,
125         .disable                = max77650_regulator_disable,
126         .list_voltage           = regulator_list_voltage_linear,
127         .map_voltage            = regulator_map_voltage_linear,
128         .get_voltage_sel        = regulator_get_voltage_sel_regmap,
129         .set_voltage_sel        = regulator_set_voltage_sel_regmap,
130         .get_current_limit      = regulator_get_current_limit_regmap,
131         .set_current_limit      = regulator_set_current_limit_regmap,
132         .set_active_discharge   = regulator_set_active_discharge_regmap,
133 };
134
135 /* Special case for max77651 SBB1 - pickable linear-range voltage mapping. */
136 static const struct regulator_ops max77651_SBB1_regulator_ops = {
137         .is_enabled             = max77650_regulator_is_enabled,
138         .enable                 = max77650_regulator_enable,
139         .disable                = max77650_regulator_disable,
140         .list_voltage           = regulator_list_voltage_pickable_linear_range,
141         .get_voltage_sel        = regulator_get_voltage_sel_pickable_regmap,
142         .set_voltage_sel        = regulator_set_voltage_sel_pickable_regmap,
143         .get_current_limit      = regulator_get_current_limit_regmap,
144         .set_current_limit      = regulator_set_current_limit_regmap,
145         .set_active_discharge   = regulator_set_active_discharge_regmap,
146 };
147
148 static struct max77650_regulator_desc max77650_LDO_desc = {
149         .desc = {
150                 .name                   = "ldo",
151                 .of_match               = of_match_ptr("ldo"),
152                 .regulators_node        = of_match_ptr("regulators"),
153                 .supply_name            = "in-ldo",
154                 .id                     = MAX77650_REGULATOR_ID_LDO,
155                 .ops                    = &max77650_regulator_LDO_ops,
156                 .min_uV                 = 1350000,
157                 .uV_step                = 12500,
158                 .n_voltages             = 128,
159                 .vsel_step              = 1,
160                 .vsel_mask              = MAX77650_REGULATOR_V_LDO_MASK,
161                 .vsel_reg               = MAX77650_REG_CNFG_LDO_A,
162                 .active_discharge_off   = MAX77650_REGULATOR_AD_DISABLED,
163                 .active_discharge_on    = MAX77650_REGULATOR_AD_ENABLED,
164                 .active_discharge_mask  = MAX77650_REGULATOR_AD_MASK,
165                 .active_discharge_reg   = MAX77650_REG_CNFG_LDO_B,
166                 .enable_time            = 100,
167                 .type                   = REGULATOR_VOLTAGE,
168                 .owner                  = THIS_MODULE,
169         },
170         .regA           = MAX77650_REG_CNFG_LDO_A,
171         .regB           = MAX77650_REG_CNFG_LDO_B,
172 };
173
174 static struct max77650_regulator_desc max77650_SBB0_desc = {
175         .desc = {
176                 .name                   = "sbb0",
177                 .of_match               = of_match_ptr("sbb0"),
178                 .regulators_node        = of_match_ptr("regulators"),
179                 .supply_name            = "in-sbb0",
180                 .id                     = MAX77650_REGULATOR_ID_SBB0,
181                 .ops                    = &max77650_regulator_SBB_ops,
182                 .min_uV                 = 800000,
183                 .uV_step                = 25000,
184                 .n_voltages             = 64,
185                 .vsel_step              = 1,
186                 .vsel_mask              = MAX77650_REGULATOR_V_SBB_MASK,
187                 .vsel_reg               = MAX77650_REG_CNFG_SBB0_A,
188                 .active_discharge_off   = MAX77650_REGULATOR_AD_DISABLED,
189                 .active_discharge_on    = MAX77650_REGULATOR_AD_ENABLED,
190                 .active_discharge_mask  = MAX77650_REGULATOR_AD_MASK,
191                 .active_discharge_reg   = MAX77650_REG_CNFG_SBB0_B,
192                 .enable_time            = 100,
193                 .type                   = REGULATOR_VOLTAGE,
194                 .owner                  = THIS_MODULE,
195                 .csel_reg               = MAX77650_REG_CNFG_SBB0_A,
196                 .csel_mask              = MAX77650_REGULATOR_CURR_LIM_MASK,
197                 .curr_table             = max77650_current_limit_table,
198                 .n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
199         },
200         .regA           = MAX77650_REG_CNFG_SBB0_A,
201         .regB           = MAX77650_REG_CNFG_SBB0_B,
202 };
203
204 static struct max77650_regulator_desc max77650_SBB1_desc = {
205         .desc = {
206                 .name                   = "sbb1",
207                 .of_match               = of_match_ptr("sbb1"),
208                 .regulators_node        = of_match_ptr("regulators"),
209                 .supply_name            = "in-sbb1",
210                 .id                     = MAX77650_REGULATOR_ID_SBB1,
211                 .ops                    = &max77650_regulator_SBB_ops,
212                 .min_uV                 = 800000,
213                 .uV_step                = 12500,
214                 .n_voltages             = 64,
215                 .vsel_step              = 1,
216                 .vsel_mask              = MAX77650_REGULATOR_V_SBB_MASK,
217                 .vsel_reg               = MAX77650_REG_CNFG_SBB1_A,
218                 .active_discharge_off   = MAX77650_REGULATOR_AD_DISABLED,
219                 .active_discharge_on    = MAX77650_REGULATOR_AD_ENABLED,
220                 .active_discharge_mask  = MAX77650_REGULATOR_AD_MASK,
221                 .active_discharge_reg   = MAX77650_REG_CNFG_SBB1_B,
222                 .enable_time            = 100,
223                 .type                   = REGULATOR_VOLTAGE,
224                 .owner                  = THIS_MODULE,
225                 .csel_reg               = MAX77650_REG_CNFG_SBB1_A,
226                 .csel_mask              = MAX77650_REGULATOR_CURR_LIM_MASK,
227                 .curr_table             = max77650_current_limit_table,
228                 .n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
229         },
230         .regA           = MAX77650_REG_CNFG_SBB1_A,
231         .regB           = MAX77650_REG_CNFG_SBB1_B,
232 };
233
234 static struct max77650_regulator_desc max77651_SBB1_desc = {
235         .desc = {
236                 .name                   = "sbb1",
237                 .of_match               = of_match_ptr("sbb1"),
238                 .regulators_node        = of_match_ptr("regulators"),
239                 .supply_name            = "in-sbb1",
240                 .id                     = MAX77650_REGULATOR_ID_SBB1,
241                 .ops                    = &max77651_SBB1_regulator_ops,
242                 .linear_range_selectors = max77651_sbb1_volt_range_sel,
243                 .linear_ranges          = max77651_sbb1_volt_ranges,
244                 .n_linear_ranges        = ARRAY_SIZE(max77651_sbb1_volt_ranges),
245                 .n_voltages             = 58,
246                 .vsel_step              = 1,
247                 .vsel_range_mask        = MAX77651_REGULATOR_V_SBB1_RANGE_MASK,
248                 .vsel_range_reg         = MAX77650_REG_CNFG_SBB1_A,
249                 .vsel_mask              = MAX77651_REGULATOR_V_SBB1_MASK,
250                 .vsel_reg               = MAX77650_REG_CNFG_SBB1_A,
251                 .active_discharge_off   = MAX77650_REGULATOR_AD_DISABLED,
252                 .active_discharge_on    = MAX77650_REGULATOR_AD_ENABLED,
253                 .active_discharge_mask  = MAX77650_REGULATOR_AD_MASK,
254                 .active_discharge_reg   = MAX77650_REG_CNFG_SBB1_B,
255                 .enable_time            = 100,
256                 .type                   = REGULATOR_VOLTAGE,
257                 .owner                  = THIS_MODULE,
258                 .csel_reg               = MAX77650_REG_CNFG_SBB1_A,
259                 .csel_mask              = MAX77650_REGULATOR_CURR_LIM_MASK,
260                 .curr_table             = max77650_current_limit_table,
261                 .n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
262         },
263         .regA           = MAX77650_REG_CNFG_SBB1_A,
264         .regB           = MAX77650_REG_CNFG_SBB1_B,
265 };
266
267 static struct max77650_regulator_desc max77650_SBB2_desc = {
268         .desc = {
269                 .name                   = "sbb2",
270                 .of_match               = of_match_ptr("sbb2"),
271                 .regulators_node        = of_match_ptr("regulators"),
272                 .supply_name            = "in-sbb0",
273                 .id                     = MAX77650_REGULATOR_ID_SBB2,
274                 .ops                    = &max77650_regulator_SBB_ops,
275                 .min_uV                 = 800000,
276                 .uV_step                = 50000,
277                 .n_voltages             = 64,
278                 .vsel_step              = 1,
279                 .vsel_mask              = MAX77650_REGULATOR_V_SBB_MASK,
280                 .vsel_reg               = MAX77650_REG_CNFG_SBB2_A,
281                 .active_discharge_off   = MAX77650_REGULATOR_AD_DISABLED,
282                 .active_discharge_on    = MAX77650_REGULATOR_AD_ENABLED,
283                 .active_discharge_mask  = MAX77650_REGULATOR_AD_MASK,
284                 .active_discharge_reg   = MAX77650_REG_CNFG_SBB2_B,
285                 .enable_time            = 100,
286                 .type                   = REGULATOR_VOLTAGE,
287                 .owner                  = THIS_MODULE,
288                 .csel_reg               = MAX77650_REG_CNFG_SBB2_A,
289                 .csel_mask              = MAX77650_REGULATOR_CURR_LIM_MASK,
290                 .curr_table             = max77650_current_limit_table,
291                 .n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
292         },
293         .regA           = MAX77650_REG_CNFG_SBB2_A,
294         .regB           = MAX77650_REG_CNFG_SBB2_B,
295 };
296
297 static struct max77650_regulator_desc max77651_SBB2_desc = {
298         .desc = {
299                 .name                   = "sbb2",
300                 .of_match               = of_match_ptr("sbb2"),
301                 .regulators_node        = of_match_ptr("regulators"),
302                 .supply_name            = "in-sbb0",
303                 .id                     = MAX77650_REGULATOR_ID_SBB2,
304                 .ops                    = &max77650_regulator_SBB_ops,
305                 .min_uV                 = 2400000,
306                 .uV_step                = 50000,
307                 .n_voltages             = 64,
308                 .vsel_step              = 1,
309                 .vsel_mask              = MAX77650_REGULATOR_V_SBB_MASK,
310                 .vsel_reg               = MAX77650_REG_CNFG_SBB2_A,
311                 .active_discharge_off   = MAX77650_REGULATOR_AD_DISABLED,
312                 .active_discharge_on    = MAX77650_REGULATOR_AD_ENABLED,
313                 .active_discharge_mask  = MAX77650_REGULATOR_AD_MASK,
314                 .active_discharge_reg   = MAX77650_REG_CNFG_SBB2_B,
315                 .enable_time            = 100,
316                 .type                   = REGULATOR_VOLTAGE,
317                 .owner                  = THIS_MODULE,
318                 .csel_reg               = MAX77650_REG_CNFG_SBB2_A,
319                 .csel_mask              = MAX77650_REGULATOR_CURR_LIM_MASK,
320                 .curr_table             = max77650_current_limit_table,
321                 .n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
322         },
323         .regA           = MAX77650_REG_CNFG_SBB2_A,
324         .regB           = MAX77650_REG_CNFG_SBB2_B,
325 };
326
327 static int max77650_regulator_probe(struct platform_device *pdev)
328 {
329         struct max77650_regulator_desc **rdescs;
330         struct max77650_regulator_desc *rdesc;
331         struct regulator_config config = { };
332         struct device *dev, *parent;
333         struct regulator_dev *rdev;
334         struct regmap *map;
335         unsigned int val;
336         int i, rv;
337
338         dev = &pdev->dev;
339         parent = dev->parent;
340
341         if (!dev->of_node)
342                 dev->of_node = parent->of_node;
343
344         rdescs = devm_kcalloc(dev, MAX77650_REGULATOR_NUM_REGULATORS,
345                               sizeof(*rdescs), GFP_KERNEL);
346         if (!rdescs)
347                 return -ENOMEM;
348
349         map = dev_get_regmap(parent, NULL);
350         if (!map)
351                 return -ENODEV;
352
353         rv = regmap_read(map, MAX77650_REG_CID, &val);
354         if (rv)
355                 return rv;
356
357         rdescs[MAX77650_REGULATOR_ID_LDO] = &max77650_LDO_desc;
358         rdescs[MAX77650_REGULATOR_ID_SBB0] = &max77650_SBB0_desc;
359
360         switch (MAX77650_CID_BITS(val)) {
361         case MAX77650_CID_77650A:
362         case MAX77650_CID_77650C:
363                 rdescs[MAX77650_REGULATOR_ID_SBB1] = &max77650_SBB1_desc;
364                 rdescs[MAX77650_REGULATOR_ID_SBB2] = &max77650_SBB2_desc;
365                 break;
366         case MAX77650_CID_77651A:
367         case MAX77650_CID_77651B:
368                 rdescs[MAX77650_REGULATOR_ID_SBB1] = &max77651_SBB1_desc;
369                 rdescs[MAX77650_REGULATOR_ID_SBB2] = &max77651_SBB2_desc;
370                 break;
371         default:
372                 return -ENODEV;
373         }
374
375         config.dev = parent;
376
377         for (i = 0; i < MAX77650_REGULATOR_NUM_REGULATORS; i++) {
378                 rdesc = rdescs[i];
379                 config.driver_data = rdesc;
380
381                 rdev = devm_regulator_register(dev, &rdesc->desc, &config);
382                 if (IS_ERR(rdev))
383                         return PTR_ERR(rdev);
384         }
385
386         return 0;
387 }
388
389 static const struct of_device_id max77650_regulator_of_match[] = {
390         { .compatible = "maxim,max77650-regulator" },
391         { }
392 };
393 MODULE_DEVICE_TABLE(of, max77650_regulator_of_match);
394
395 static struct platform_driver max77650_regulator_driver = {
396         .driver = {
397                 .name = "max77650-regulator",
398                 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
399                 .of_match_table = max77650_regulator_of_match,
400         },
401         .probe = max77650_regulator_probe,
402 };
403 module_platform_driver(max77650_regulator_driver);
404
405 MODULE_DESCRIPTION("MAXIM 77650/77651 regulator driver");
406 MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
407 MODULE_LICENSE("GPL v2");
408 MODULE_ALIAS("platform:max77650-regulator");