• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
swxilim_select(struct pf8x00_chip * chip,int id,int ilim)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 
handle_ilim_property(struct device_node * np,const struct regulator_desc * desc,struct regulator_config * config)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 
handle_shift_property(struct device_node * np,const struct regulator_desc * desc,struct regulator_config * config)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 
pf8x00_of_parse_cb(struct device_node * np,const struct regulator_desc * desc,struct regulator_config * config)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 
pf8x00_suspend_enable(struct regulator_dev * rdev)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 
pf8x00_suspend_disable(struct regulator_dev * rdev)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 
pf8x00_set_suspend_voltage(struct regulator_dev * rdev,int uV)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 
pf8x00_identify(struct pf8x00_chip * chip)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 
pf8x00_i2c_probe(struct i2c_client * client)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 		.of_match_table = pf8x00_dt_ids,
611 	},
612 	.probe_new = pf8x00_i2c_probe,
613 };
614 module_i2c_driver(pf8x00_regulator_driver);
615 
616 MODULE_AUTHOR("Jagan Teki <jagan@amarulasolutions.com>");
617 MODULE_AUTHOR("Troy Kisky <troy.kisky@boundarydevices.com>");
618 MODULE_DESCRIPTION("Regulator Driver for NXP's PF8100/PF8121A/PF8200 PMIC");
619 MODULE_LICENSE("GPL v2");
620