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