Merge tag 'apparmor-pr-2023-07-06' of git://git.kernel.org/pub/scm/linux/kernel/git...
[platform/kernel/linux-starfive.git] / drivers / regulator / pf8x00-regulator.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2017 NXP
4  * Copyright (C) 2019 Boundary Devices
5  * Copyright (C) 2020 Amarula Solutions(India)
6  */
7
8 #include <linux/delay.h>
9 #include <linux/err.h>
10 #include <linux/gpio/consumer.h>
11 #include <linux/i2c.h>
12 #include <linux/module.h>
13 #include <linux/regmap.h>
14 #include <linux/regulator/driver.h>
15 #include <linux/regulator/machine.h>
16
17 /* registers */
18 #define PF8X00_DEVICEID                 0x00
19 #define PF8X00_REVID                    0x01
20 #define PF8X00_EMREV                    0x02
21 #define PF8X00_PROGID                   0x03
22 #define PF8X00_IMS_INT                  0x04
23 #define PF8X00_IMS_THERM                0x07
24 #define PF8X00_SW_MODE_INT              0x0a
25 #define PF8X00_SW_MODE_MASK             0x0b
26 #define PF8X00_IMS_SW_ILIM              0x12
27 #define PF8X00_IMS_LDO_ILIM             0x15
28 #define PF8X00_IMS_SW_UV                0x18
29 #define PF8X00_IMS_SW_OV                0x1b
30 #define PF8X00_IMS_LDO_UV               0x1e
31 #define PF8X00_IMS_LDO_OV               0x21
32 #define PF8X00_IMS_PWRON                0x24
33 #define PF8X00_SYS_INT                  0x27
34 #define PF8X00_HARD_FAULT               0x29
35 #define PF8X00_FSOB_FLAGS               0x2a
36 #define PF8X00_FSOB_SELECT              0x2b
37 #define PF8X00_ABIST_OV1                0x2c
38 #define PF8X00_ABIST_OV2                0x2d
39 #define PF8X00_ABIST_UV1                0x2e
40 #define PF8X00_ABIST_UV2                0x2f
41 #define PF8X00_TEST_FLAGS               0x30
42 #define PF8X00_ABIST_RUN                0x31
43 #define PF8X00_RANDOM_GEN               0x33
44 #define PF8X00_RANDOM_CHK               0x34
45 #define PF8X00_VMONEN1                  0x35
46 #define PF8X00_VMONEN2                  0x36
47 #define PF8X00_CTRL1                    0x37
48 #define PF8X00_CTRL2                    0x38
49 #define PF8X00_CTRL3                    0x39
50 #define PF8X00_PWRUP_CTRL               0x3a
51 #define PF8X00_RESETBMCU                0x3c
52 #define PF8X00_PGOOD                    0x3d
53 #define PF8X00_PWRDN_DLY1               0x3e
54 #define PF8X00_PWRDN_DLY2               0x3f
55 #define PF8X00_FREQ_CTRL                0x40
56 #define PF8X00_COINCELL_CTRL            0x41
57 #define PF8X00_PWRON                    0x42
58 #define PF8X00_WD_CONFIG                0x43
59 #define PF8X00_WD_CLEAR                 0x44
60 #define PF8X00_WD_EXPIRE                0x45
61 #define PF8X00_WD_COUNTER               0x46
62 #define PF8X00_FAULT_COUNTER            0x47
63 #define PF8X00_FSAFE_COUNTER            0x48
64 #define PF8X00_FAULT_TIMER              0x49
65 #define PF8X00_AMUX                     0x4a
66 #define PF8X00_SW1_CONFIG1              0x4d
67 #define PF8X00_LDO1_CONFIG1             0x85
68 #define PF8X00_VSNVS_CONFIG1            0x9d
69 #define PF8X00_PAGE_SELECT              0x9f
70
71 /* regulators */
72 enum pf8x00_regulators {
73         PF8X00_LDO1,
74         PF8X00_LDO2,
75         PF8X00_LDO3,
76         PF8X00_LDO4,
77         PF8X00_BUCK1,
78         PF8X00_BUCK2,
79         PF8X00_BUCK3,
80         PF8X00_BUCK4,
81         PF8X00_BUCK5,
82         PF8X00_BUCK6,
83         PF8X00_BUCK7,
84         PF8X00_VSNVS,
85
86         PF8X00_MAX_REGULATORS,
87 };
88
89 enum pf8x00_buck_states {
90         SW_CONFIG1,
91         SW_CONFIG2,
92         SW_PWRUP,
93         SW_MODE1,
94         SW_RUN_VOLT,
95         SW_STBY_VOLT,
96 };
97 #define PF8X00_SW_BASE(i)               (8 * (i - PF8X00_BUCK1) + PF8X00_SW1_CONFIG1)
98
99 enum pf8x00_ldo_states {
100         LDO_CONFIG1,
101         LDO_CONFIG2,
102         LDO_PWRUP,
103         LDO_RUN_VOLT,
104         LDO_STBY_VOLT,
105 };
106 #define PF8X00_LDO_BASE(i)              (6 * (i - PF8X00_LDO1) + PF8X00_LDO1_CONFIG1)
107
108 enum swxilim_bits {
109         SWXILIM_2100_MA,
110         SWXILIM_2600_MA,
111         SWXILIM_3000_MA,
112         SWXILIM_4500_MA,
113 };
114 #define PF8X00_SWXILIM_SHIFT            3
115 #define PF8X00_SWXILIM_MASK             GENMASK(4, 3)
116 #define PF8X00_SWXPHASE_MASK            GENMASK(2, 0)
117 #define PF8X00_SWXPHASE_SHIFT           7
118
119 enum pf8x00_devid {
120         PF8100                  = 0x0,
121         PF8121A                 = BIT(1),
122         PF8200                  = BIT(3),
123 };
124 #define PF8X00_FAM                      BIT(6)
125 #define PF8X00_DEVICE_FAM_MASK          GENMASK(7, 4)
126 #define PF8X00_DEVICE_ID_MASK           GENMASK(3, 0)
127
128 struct pf8x00_regulator_data {
129         struct regulator_desc desc;
130         unsigned int suspend_enable_reg;
131         unsigned int suspend_enable_mask;
132         unsigned int suspend_voltage_reg;
133         unsigned int suspend_voltage_cache;
134 };
135
136 struct pf8x00_chip {
137         struct regmap *regmap;
138         struct device *dev;
139 };
140
141 static const struct regmap_config pf8x00_regmap_config = {
142         .reg_bits = 8,
143         .val_bits = 8,
144         .max_register = PF8X00_PAGE_SELECT,
145         .cache_type = REGCACHE_RBTREE,
146 };
147
148 /* VLDOx output: 1.5V to 5.0V */
149 static const int pf8x00_ldo_voltages[] = {
150         1500000, 1600000, 1800000, 1850000, 2150000, 2500000, 2800000, 3000000,
151         3100000, 3150000, 3200000, 3300000, 3350000, 1650000, 1700000, 5000000,
152 };
153
154 /* Output: 2.1A to 4.5A */
155 static const unsigned int pf8x00_sw_current_table[] = {
156         2100000, 2600000, 3000000, 4500000,
157 };
158
159 /* Output: 0.4V to 1.8V */
160 #define PF8XOO_SW1_6_VOLTAGE_NUM 0xB2
161 static const struct linear_range pf8x00_sw1_to_6_voltages[] = {
162         REGULATOR_LINEAR_RANGE(400000, 0x00, 0xB0, 6250),
163         REGULATOR_LINEAR_RANGE(1800000, 0xB1, 0xB1, 0),
164 };
165
166 /* Output: 1.0V to 4.1V */
167 static const int pf8x00_sw7_voltages[] = {
168         1000000, 1100000, 1200000, 1250000, 1300000, 1350000, 1500000, 1600000,
169         1800000, 1850000, 2000000, 2100000, 2150000, 2250000, 2300000, 2400000,
170         2500000, 2800000, 3150000, 3200000, 3250000, 3300000, 3350000, 3400000,
171         3500000, 3800000, 4000000, 4100000, 4100000, 4100000, 4100000, 4100000,
172 };
173
174 /* Output: 1.8V, 3.0V, or 3.3V */
175 static const int pf8x00_vsnvs_voltages[] = {
176         0, 1800000, 3000000, 3300000,
177 };
178
179 static void swxilim_select(struct pf8x00_chip *chip, int id, int ilim)
180 {
181         u8 ilim_sel;
182         u8 reg = PF8X00_SW_BASE(id) + SW_CONFIG2;
183
184         switch (ilim) {
185         case 2100:
186                 ilim_sel = SWXILIM_2100_MA;
187                 break;
188         case 2600:
189                 ilim_sel = SWXILIM_2600_MA;
190                 break;
191         case 3000:
192                 ilim_sel = SWXILIM_3000_MA;
193                 break;
194         case 4500:
195                 ilim_sel = SWXILIM_4500_MA;
196                 break;
197         default:
198                 ilim_sel = SWXILIM_2100_MA;
199                 break;
200         }
201
202         regmap_update_bits(chip->regmap, reg,
203                                         PF8X00_SWXILIM_MASK,
204                                         ilim_sel << PF8X00_SWXILIM_SHIFT);
205 }
206
207 static void handle_ilim_property(struct device_node *np,
208                               const struct regulator_desc *desc,
209                               struct regulator_config *config)
210 {
211         struct pf8x00_chip *chip = config->driver_data;
212         int ret;
213         int val;
214
215         if ((desc->id >= PF8X00_BUCK1) && (desc->id <= PF8X00_BUCK7)) {
216                 ret = of_property_read_u32(np, "nxp,ilim-ma", &val);
217                 if (ret) {
218                         dev_dbg(chip->dev, "unspecified ilim for BUCK%d, use value stored in OTP\n",
219                                 desc->id - PF8X00_LDO4);
220                         return;
221                 }
222
223                 dev_warn(chip->dev, "nxp,ilim-ma is deprecated, please use regulator-max-microamp\n");
224                 swxilim_select(chip, desc->id, val);
225
226         } else
227                 dev_warn(chip->dev, "nxp,ilim-ma used with incorrect regulator (%d)\n", desc->id);
228 }
229
230 static void handle_shift_property(struct device_node *np,
231                               const struct regulator_desc *desc,
232                               struct regulator_config *config)
233 {
234         unsigned char id = desc->id - PF8X00_LDO4;
235         unsigned char reg = PF8X00_SW_BASE(id) + SW_CONFIG2;
236         struct pf8x00_chip *chip = config->driver_data;
237
238         int phase;
239         int val;
240         int ret;
241         if ((desc->id >= PF8X00_BUCK1) && (desc->id <= PF8X00_BUCK7)) {
242                 ret = of_property_read_u32(np, "nxp,phase-shift", &val);
243                 if (ret) {
244                         dev_dbg(chip->dev,
245                                 "unspecified phase-shift for BUCK%d, using OTP configuration\n",
246                                 id);
247                         return;
248                 }
249
250                 if (val < 0 || val > 315 || val % 45 != 0) {
251                         dev_warn(config->dev,
252                                 "invalid phase_shift %d for BUCK%d, using OTP configuration\n",
253                                 val, id);
254                         return;
255                 }
256
257                 phase = val / 45;
258
259                 if (phase >= 1)
260                         phase -= 1;
261                 else
262                         phase = PF8X00_SWXPHASE_SHIFT;
263
264                 regmap_update_bits(chip->regmap, reg,
265                                 PF8X00_SWXPHASE_MASK,
266                                 phase);
267         } else
268                 dev_warn(chip->dev, "nxp,phase-shift used with incorrect regulator (%d)\n", id);
269
270 }
271
272 static int pf8x00_of_parse_cb(struct device_node *np,
273                               const struct regulator_desc *desc,
274                               struct regulator_config *config)
275 {
276
277         handle_ilim_property(np, desc, config);
278         handle_shift_property(np, desc, config);
279
280         return 0;
281 }
282
283 static int pf8x00_suspend_enable(struct regulator_dev *rdev)
284 {
285         struct pf8x00_regulator_data *regl = rdev_get_drvdata(rdev);
286         struct regmap *rmap = rdev_get_regmap(rdev);
287
288         return regmap_update_bits(rmap, regl->suspend_enable_reg,
289                                   regl->suspend_enable_mask,
290                                   regl->suspend_enable_mask);
291 }
292
293 static int pf8x00_suspend_disable(struct regulator_dev *rdev)
294 {
295         struct pf8x00_regulator_data *regl = rdev_get_drvdata(rdev);
296         struct regmap *rmap = rdev_get_regmap(rdev);
297
298         return regmap_update_bits(rmap, regl->suspend_enable_reg,
299                                   regl->suspend_enable_mask, 0);
300 }
301
302 static int pf8x00_set_suspend_voltage(struct regulator_dev *rdev, int uV)
303 {
304         struct pf8x00_regulator_data *regl = rdev_get_drvdata(rdev);
305         int ret;
306
307         if (regl->suspend_voltage_cache == uV)
308                 return 0;
309
310         ret = regulator_map_voltage_iterate(rdev, uV, uV);
311         if (ret < 0) {
312                 dev_err(rdev_get_dev(rdev), "failed to map %i uV\n", uV);
313                 return ret;
314         }
315
316         dev_dbg(rdev_get_dev(rdev), "uV: %i, reg: 0x%x, msk: 0x%x, val: 0x%x\n",
317                 uV, regl->suspend_voltage_reg, regl->desc.vsel_mask, ret);
318         ret = regmap_update_bits(rdev->regmap, regl->suspend_voltage_reg,
319                                  regl->desc.vsel_mask, ret);
320         if (ret < 0) {
321                 dev_err(rdev_get_dev(rdev), "failed to set %i uV\n", uV);
322                 return ret;
323         }
324
325         regl->suspend_voltage_cache = uV;
326
327         return 0;
328 }
329
330 static const struct regulator_ops pf8x00_ldo_ops = {
331         .enable = regulator_enable_regmap,
332         .disable = regulator_disable_regmap,
333         .is_enabled = regulator_is_enabled_regmap,
334         .list_voltage = regulator_list_voltage_table,
335         .set_voltage_sel = regulator_set_voltage_sel_regmap,
336         .get_voltage_sel = regulator_get_voltage_sel_regmap,
337         .set_suspend_enable = pf8x00_suspend_enable,
338         .set_suspend_disable = pf8x00_suspend_disable,
339         .set_suspend_voltage = pf8x00_set_suspend_voltage,
340 };
341
342
343 static const struct regulator_ops pf8x00_buck1_6_ops = {
344         .enable = regulator_enable_regmap,
345         .disable = regulator_disable_regmap,
346         .is_enabled = regulator_is_enabled_regmap,
347         .list_voltage = regulator_list_voltage_linear_range,
348         .set_voltage_sel = regulator_set_voltage_sel_regmap,
349         .get_voltage_sel = regulator_get_voltage_sel_regmap,
350         .get_current_limit = regulator_get_current_limit_regmap,
351         .set_current_limit = regulator_set_current_limit_regmap,
352         .set_suspend_enable = pf8x00_suspend_enable,
353         .set_suspend_disable = pf8x00_suspend_disable,
354         .set_suspend_voltage = pf8x00_set_suspend_voltage,
355 };
356
357 static const struct regulator_ops pf8x00_buck7_ops = {
358         .enable = regulator_enable_regmap,
359         .disable = regulator_disable_regmap,
360         .is_enabled = regulator_is_enabled_regmap,
361         .list_voltage = regulator_list_voltage_table,
362         .map_voltage = regulator_map_voltage_ascend,
363         .set_voltage_sel = regulator_set_voltage_sel_regmap,
364         .get_voltage_sel = regulator_get_voltage_sel_regmap,
365         .get_current_limit = regulator_get_current_limit_regmap,
366         .set_current_limit = regulator_set_current_limit_regmap,
367         .set_suspend_enable = pf8x00_suspend_enable,
368         .set_suspend_disable = pf8x00_suspend_disable,
369 };
370
371 static const struct regulator_ops pf8x00_vsnvs_ops = {
372         .enable = regulator_enable_regmap,
373         .disable = regulator_disable_regmap,
374         .is_enabled = regulator_is_enabled_regmap,
375         .list_voltage = regulator_list_voltage_table,
376         .map_voltage = regulator_map_voltage_ascend,
377         .set_voltage_sel = regulator_set_voltage_sel_regmap,
378         .get_voltage_sel = regulator_get_voltage_sel_regmap,
379 };
380
381 #define PF8X00LDO(_id, _name, base, voltages)                   \
382         [PF8X00_LDO ## _id] = {                                 \
383                 .desc = {                                       \
384                         .name = _name,                          \
385                         .of_match = _name,                      \
386                         .regulators_node = "regulators",        \
387                         .n_voltages = ARRAY_SIZE(voltages),     \
388                         .ops = &pf8x00_ldo_ops,                 \
389                         .type = REGULATOR_VOLTAGE,              \
390                         .id = PF8X00_LDO ## _id,                \
391                         .owner = THIS_MODULE,                   \
392                         .volt_table = voltages,                 \
393                         .vsel_reg = (base) + LDO_RUN_VOLT,      \
394                         .vsel_mask = 0xff,                      \
395                         .enable_reg = (base) + LDO_CONFIG2,     \
396                         .enable_val = 0x2,                      \
397                         .disable_val = 0x0,                     \
398                         .enable_mask = 2,                       \
399                 },                                              \
400                 .suspend_enable_reg = (base) + LDO_CONFIG2,     \
401                 .suspend_enable_mask = 1,                       \
402                 .suspend_voltage_reg = (base) + LDO_STBY_VOLT,  \
403         }
404
405 #define PF8X00BUCK(_id, _name, base, voltages)                  \
406         [PF8X00_BUCK ## _id] = {                                \
407                 .desc = {                                       \
408                         .name = _name,                          \
409                         .of_match = _name,                      \
410                         .regulators_node = "regulators",        \
411                         .of_parse_cb = pf8x00_of_parse_cb,      \
412                         .n_voltages = PF8XOO_SW1_6_VOLTAGE_NUM, \
413                         .ops = &pf8x00_buck1_6_ops,             \
414                         .type = REGULATOR_VOLTAGE,              \
415                         .id = PF8X00_BUCK ## _id,               \
416                         .owner = THIS_MODULE,                   \
417                         .ramp_delay = 19000,                    \
418                         .linear_ranges = pf8x00_sw1_to_6_voltages, \
419                         .n_linear_ranges = \
420                                 ARRAY_SIZE(pf8x00_sw1_to_6_voltages), \
421                         .vsel_reg = (base) + SW_RUN_VOLT,       \
422                         .vsel_mask = 0xff,                      \
423                         .curr_table = pf8x00_sw_current_table, \
424                         .n_current_limits = \
425                                 ARRAY_SIZE(pf8x00_sw_current_table), \
426                         .csel_reg = (base) + SW_CONFIG2,        \
427                         .csel_mask = PF8X00_SWXILIM_MASK,       \
428                         .enable_reg = (base) + SW_MODE1,        \
429                         .enable_val = 0x3,                      \
430                         .disable_val = 0x0,                     \
431                         .enable_mask = 0x3,                     \
432                         .enable_time = 500,                     \
433                 },                                              \
434                 .suspend_enable_reg = (base) + SW_MODE1,        \
435                 .suspend_enable_mask = 0xc,                     \
436                 .suspend_voltage_reg = (base) + SW_STBY_VOLT,   \
437         }
438
439 #define PF8X00BUCK7(_name, base, voltages)                      \
440         [PF8X00_BUCK7] = {                              \
441                 .desc = {                                       \
442                         .name = _name,                          \
443                         .of_match = _name,                      \
444                         .regulators_node = "regulators",        \
445                         .of_parse_cb = pf8x00_of_parse_cb,      \
446                         .n_voltages = ARRAY_SIZE(voltages),     \
447                         .ops = &pf8x00_buck7_ops,               \
448                         .type = REGULATOR_VOLTAGE,              \
449                         .id = PF8X00_BUCK7,             \
450                         .owner = THIS_MODULE,                   \
451                         .ramp_delay = 19000,                    \
452                         .volt_table = voltages,                 \
453                         .vsel_reg = (base) + SW_RUN_VOLT,       \
454                         .vsel_mask = 0xff,                      \
455                         .curr_table = pf8x00_sw_current_table, \
456                         .n_current_limits = \
457                                 ARRAY_SIZE(pf8x00_sw_current_table), \
458                         .csel_reg = (base) + SW_CONFIG2,        \
459                         .csel_mask = PF8X00_SWXILIM_MASK,       \
460                         .enable_reg = (base) + SW_MODE1,        \
461                         .enable_val = 0x3,                      \
462                         .disable_val = 0x0,                     \
463                         .enable_mask = 0x3,                     \
464                         .enable_time = 500,                     \
465                 },                                              \
466         }
467
468
469 #define PF8X00VSNVS(_name, base, voltages)                      \
470         [PF8X00_VSNVS] = {                                      \
471                 .desc = {                                       \
472                         .name = _name,                          \
473                         .of_match = _name,                      \
474                         .regulators_node = "regulators",        \
475                         .n_voltages = ARRAY_SIZE(voltages),     \
476                         .ops = &pf8x00_vsnvs_ops,               \
477                         .type = REGULATOR_VOLTAGE,              \
478                         .id = PF8X00_VSNVS,                     \
479                         .owner = THIS_MODULE,                   \
480                         .volt_table = voltages,                 \
481                         .vsel_reg = (base),                     \
482                         .vsel_mask = 0x3,                       \
483                 },                                              \
484         }
485
486 static struct pf8x00_regulator_data pf8x00_regs_data[PF8X00_MAX_REGULATORS] = {
487         PF8X00LDO(1, "ldo1", PF8X00_LDO_BASE(PF8X00_LDO1), pf8x00_ldo_voltages),
488         PF8X00LDO(2, "ldo2", PF8X00_LDO_BASE(PF8X00_LDO2), pf8x00_ldo_voltages),
489         PF8X00LDO(3, "ldo3", PF8X00_LDO_BASE(PF8X00_LDO3), pf8x00_ldo_voltages),
490         PF8X00LDO(4, "ldo4", PF8X00_LDO_BASE(PF8X00_LDO4), pf8x00_ldo_voltages),
491         PF8X00BUCK(1, "buck1", PF8X00_SW_BASE(PF8X00_BUCK1), pf8x00_sw1_to_6_voltages),
492         PF8X00BUCK(2, "buck2", PF8X00_SW_BASE(PF8X00_BUCK2), pf8x00_sw1_to_6_voltages),
493         PF8X00BUCK(3, "buck3", PF8X00_SW_BASE(PF8X00_BUCK3), pf8x00_sw1_to_6_voltages),
494         PF8X00BUCK(4, "buck4", PF8X00_SW_BASE(PF8X00_BUCK4), pf8x00_sw1_to_6_voltages),
495         PF8X00BUCK(5, "buck5", PF8X00_SW_BASE(PF8X00_BUCK5), pf8x00_sw1_to_6_voltages),
496         PF8X00BUCK(6, "buck6", PF8X00_SW_BASE(PF8X00_BUCK6), pf8x00_sw1_to_6_voltages),
497         PF8X00BUCK7("buck7", PF8X00_SW_BASE(PF8X00_BUCK7), pf8x00_sw7_voltages),
498         PF8X00VSNVS("vsnvs", PF8X00_VSNVS_CONFIG1, pf8x00_vsnvs_voltages),
499 };
500
501 static int pf8x00_identify(struct pf8x00_chip *chip)
502 {
503         unsigned int value;
504         u8 dev_fam, dev_id;
505         const char *name = NULL;
506         int ret;
507
508         ret = regmap_read(chip->regmap, PF8X00_DEVICEID, &value);
509         if (ret) {
510                 dev_err(chip->dev, "failed to read chip family\n");
511                 return ret;
512         }
513
514         dev_fam = value & PF8X00_DEVICE_FAM_MASK;
515         switch (dev_fam) {
516         case PF8X00_FAM:
517                 break;
518         default:
519                 dev_err(chip->dev,
520                         "Chip 0x%x is not from PF8X00 family\n", dev_fam);
521                 return ret;
522         }
523
524         dev_id = value & PF8X00_DEVICE_ID_MASK;
525         switch (dev_id) {
526         case PF8100:
527                 name = "PF8100";
528                 break;
529         case PF8121A:
530                 name = "PF8121A";
531                 break;
532         case PF8200:
533                 name = "PF8200";
534                 break;
535         default:
536                 dev_err(chip->dev, "Unknown pf8x00 device id 0x%x\n", dev_id);
537                 return -ENODEV;
538         }
539
540         dev_info(chip->dev, "%s PMIC found.\n", name);
541
542         return 0;
543 }
544
545 static int pf8x00_i2c_probe(struct i2c_client *client)
546 {
547         struct regulator_config config = { NULL, };
548         struct pf8x00_chip *chip;
549         int id;
550         int ret;
551
552         chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
553         if (!chip)
554                 return -ENOMEM;
555
556         i2c_set_clientdata(client, chip);
557         chip->dev = &client->dev;
558
559         chip->regmap = devm_regmap_init_i2c(client, &pf8x00_regmap_config);
560         if (IS_ERR(chip->regmap)) {
561                 ret = PTR_ERR(chip->regmap);
562                 dev_err(&client->dev,
563                         "regmap allocation failed with err %d\n", ret);
564                 return ret;
565         }
566
567         ret = pf8x00_identify(chip);
568         if (ret)
569                 return ret;
570
571         for (id = 0; id < ARRAY_SIZE(pf8x00_regs_data); id++) {
572                 struct pf8x00_regulator_data *data = &pf8x00_regs_data[id];
573                 struct regulator_dev *rdev;
574
575                 config.dev = chip->dev;
576                 config.driver_data = data;
577                 config.regmap = chip->regmap;
578
579                 rdev = devm_regulator_register(&client->dev, &data->desc, &config);
580                 if (IS_ERR(rdev)) {
581                         dev_err(&client->dev,
582                                 "failed to register %s regulator\n", data->desc.name);
583                         return PTR_ERR(rdev);
584                 }
585         }
586
587         return 0;
588 }
589
590 static const struct of_device_id pf8x00_dt_ids[] = {
591         { .compatible = "nxp,pf8100",},
592         { .compatible = "nxp,pf8121a",},
593         { .compatible = "nxp,pf8200",},
594         { }
595 };
596 MODULE_DEVICE_TABLE(of, pf8x00_dt_ids);
597
598 static const struct i2c_device_id pf8x00_i2c_id[] = {
599         { "pf8100", 0 },
600         { "pf8121a", 0 },
601         { "pf8200", 0 },
602         {},
603 };
604 MODULE_DEVICE_TABLE(i2c, pf8x00_i2c_id);
605
606 static struct i2c_driver pf8x00_regulator_driver = {
607         .id_table = pf8x00_i2c_id,
608         .driver = {
609                 .name = "pf8x00",
610                 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
611                 .of_match_table = pf8x00_dt_ids,
612         },
613         .probe = pf8x00_i2c_probe,
614 };
615 module_i2c_driver(pf8x00_regulator_driver);
616
617 MODULE_AUTHOR("Jagan Teki <jagan@amarulasolutions.com>");
618 MODULE_AUTHOR("Troy Kisky <troy.kisky@boundarydevices.com>");
619 MODULE_DESCRIPTION("Regulator Driver for NXP's PF8100/PF8121A/PF8200 PMIC");
620 MODULE_LICENSE("GPL v2");