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_DEFAULT		0
118 #define PF8X00_SWXPHASE_SHIFT		7
119 
120 enum pf8x00_devid {
121 	PF8100			= 0x0,
122 	PF8121A			= BIT(1),
123 	PF8200			= BIT(3),
124 };
125 #define PF8X00_FAM			BIT(6)
126 #define PF8X00_DEVICE_FAM_MASK		GENMASK(7, 4)
127 #define PF8X00_DEVICE_ID_MASK		GENMASK(3, 0)
128 
129 struct pf8x00_regulator {
130 	struct regulator_desc desc;
131 	u8 ilim;
132 	u8 phase_shift;
133 };
134 
135 struct pf8x00_chip {
136 	struct regmap *regmap;
137 	struct device *dev;
138 };
139 
140 static const struct regmap_config pf8x00_regmap_config = {
141 	.reg_bits = 8,
142 	.val_bits = 8,
143 	.max_register = PF8X00_PAGE_SELECT,
144 	.cache_type = REGCACHE_RBTREE,
145 };
146 
147 /* VLDOx output: 1.5V to 5.0V */
148 static const int pf8x00_ldo_voltages[] = {
149 	1500000, 1600000, 1800000, 1850000, 2150000, 2500000, 2800000, 3000000,
150 	3100000, 3150000, 3200000, 3300000, 3350000, 1650000, 1700000, 5000000,
151 };
152 
153 #define SWV(i)		(6250 * i + 400000)
154 #define SWV_LINE(i)	SWV(i*8+0), SWV(i*8+1), SWV(i*8+2), SWV(i*8+3), \
155 			SWV(i*8+4), SWV(i*8+5), SWV(i*8+6), SWV(i*8+7)
156 
157 /* Output: 0.4V to 1.8V */
158 static const int pf8x00_sw1_to_6_voltages[] = {
159 	SWV_LINE(0),
160 	SWV_LINE(1),
161 	SWV_LINE(2),
162 	SWV_LINE(3),
163 	SWV_LINE(4),
164 	SWV_LINE(5),
165 	SWV_LINE(6),
166 	SWV_LINE(7),
167 	SWV_LINE(8),
168 	SWV_LINE(9),
169 	SWV_LINE(10),
170 	SWV_LINE(11),
171 	SWV_LINE(12),
172 	SWV_LINE(13),
173 	SWV_LINE(14),
174 	SWV_LINE(15),
175 	SWV_LINE(16),
176 	SWV_LINE(17),
177 	SWV_LINE(18),
178 	SWV_LINE(19),
179 	SWV_LINE(20),
180 	SWV_LINE(21),
181 	1500000, 1800000,
182 };
183 
184 /* Output: 1.0V to 4.1V */
185 static const int pf8x00_sw7_voltages[] = {
186 	1000000, 1100000, 1200000, 1250000, 1300000, 1350000, 1500000, 1600000,
187 	1800000, 1850000, 2000000, 2100000, 2150000, 2250000, 2300000, 2400000,
188 	2500000, 2800000, 3150000, 3200000, 3250000, 3300000, 3350000, 3400000,
189 	3500000, 3800000, 4000000, 4100000, 4100000, 4100000, 4100000, 4100000,
190 };
191 
192 /* Output: 1.8V, 3.0V, or 3.3V */
193 static const int pf8x00_vsnvs_voltages[] = {
194 	0, 1800000, 3000000, 3300000,
195 };
196 
197 static struct pf8x00_regulator *desc_to_regulator(const struct regulator_desc *desc)
198 {
199 	return container_of(desc, struct pf8x00_regulator, desc);
200 }
201 
202 static void swxilim_select(const struct regulator_desc *desc, int ilim)
203 {
204 	struct pf8x00_regulator *data = desc_to_regulator(desc);
205 	u8 ilim_sel;
206 
207 	switch (ilim) {
208 	case 2100:
209 		ilim_sel = SWXILIM_2100_MA;
210 		break;
211 	case 2600:
212 		ilim_sel = SWXILIM_2600_MA;
213 		break;
214 	case 3000:
215 		ilim_sel = SWXILIM_3000_MA;
216 		break;
217 	case 4500:
218 		ilim_sel = SWXILIM_4500_MA;
219 		break;
220 	default:
221 		ilim_sel = SWXILIM_2100_MA;
222 		break;
223 	}
224 
225 	data->ilim = ilim_sel;
226 }
227 
228 static int pf8x00_of_parse_cb(struct device_node *np,
229 			      const struct regulator_desc *desc,
230 			      struct regulator_config *config)
231 {
232 	struct pf8x00_regulator *data = desc_to_regulator(desc);
233 	struct pf8x00_chip *chip = config->driver_data;
234 	int phase;
235 	int val;
236 	int ret;
237 
238 	ret = of_property_read_u32(np, "nxp,ilim-ma", &val);
239 	if (ret)
240 		dev_dbg(chip->dev, "unspecified ilim for BUCK%d, use 2100 mA\n",
241 			desc->id - PF8X00_LDO4);
242 
243 	swxilim_select(desc, val);
244 
245 	ret = of_property_read_u32(np, "nxp,phase-shift", &val);
246 	if (ret) {
247 		dev_dbg(chip->dev,
248 			"unspecified phase-shift for BUCK%d, use 0 degrees\n",
249 			desc->id - PF8X00_LDO4);
250 		val = PF8X00_SWXPHASE_DEFAULT;
251 	}
252 
253 	phase = val / 45;
254 	if ((phase * 45) != val) {
255 		dev_warn(config->dev,
256 			 "invalid phase_shift %d for BUCK%d, use 0 degrees\n",
257 			 (phase * 45), desc->id - PF8X00_LDO4);
258 		phase = PF8X00_SWXPHASE_SHIFT;
259 	}
260 
261 	data->phase_shift = (phase >= 1) ? phase - 1 : PF8X00_SWXPHASE_SHIFT;
262 
263 	return 0;
264 }
265 
266 static const struct regulator_ops pf8x00_ldo_ops = {
267 	.enable = regulator_enable_regmap,
268 	.disable = regulator_disable_regmap,
269 	.is_enabled = regulator_is_enabled_regmap,
270 	.list_voltage = regulator_list_voltage_table,
271 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
272 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
273 };
274 
275 static const struct regulator_ops pf8x00_buck_ops = {
276 	.enable = regulator_enable_regmap,
277 	.disable = regulator_disable_regmap,
278 	.is_enabled = regulator_is_enabled_regmap,
279 	.list_voltage = regulator_list_voltage_table,
280 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
281 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
282 };
283 
284 static const struct regulator_ops pf8x00_vsnvs_ops = {
285 	.enable = regulator_enable_regmap,
286 	.disable = regulator_disable_regmap,
287 	.is_enabled = regulator_is_enabled_regmap,
288 	.list_voltage = regulator_list_voltage_table,
289 	.map_voltage = regulator_map_voltage_ascend,
290 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
291 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
292 };
293 
294 #define PF8X00LDO(_id, _name, base, voltages)			\
295 	[PF8X00_LDO ## _id] = {					\
296 		.desc = {					\
297 			.name = _name,				\
298 			.of_match = _name,			\
299 			.regulators_node = "regulators",	\
300 			.n_voltages = ARRAY_SIZE(voltages),	\
301 			.ops = &pf8x00_ldo_ops,			\
302 			.type = REGULATOR_VOLTAGE,		\
303 			.id = PF8X00_LDO ## _id,		\
304 			.owner = THIS_MODULE,			\
305 			.volt_table = voltages,			\
306 			.vsel_reg = (base) + LDO_RUN_VOLT,	\
307 			.vsel_mask = 0xff,			\
308 			.enable_reg = (base) + LDO_CONFIG2,	\
309 			.enable_val = 0x2,			\
310 			.disable_val = 0x0,			\
311 			.enable_mask = 2,			\
312 		},						\
313 	}
314 
315 #define PF8X00BUCK(_id, _name, base, voltages)			\
316 	[PF8X00_BUCK ## _id] = {				\
317 		.desc = {					\
318 			.name = _name,				\
319 			.of_match = _name,			\
320 			.regulators_node = "regulators",	\
321 			.of_parse_cb = pf8x00_of_parse_cb,	\
322 			.n_voltages = ARRAY_SIZE(voltages),	\
323 			.ops = &pf8x00_buck_ops,		\
324 			.type = REGULATOR_VOLTAGE,		\
325 			.id = PF8X00_BUCK ## _id,		\
326 			.owner = THIS_MODULE,			\
327 			.volt_table = voltages,			\
328 			.vsel_reg = (base) + SW_RUN_VOLT,	\
329 			.vsel_mask = 0xff,			\
330 			.enable_reg = (base) + SW_MODE1,	\
331 			.enable_val = 0x3,			\
332 			.disable_val = 0x0,			\
333 			.enable_mask = 0x3,			\
334 			.enable_time = 500,			\
335 		},						\
336 	}
337 
338 #define PF8X00VSNVS(_name, base, voltages)			\
339 	[PF8X00_VSNVS] = {					\
340 		.desc = {					\
341 			.name = _name,				\
342 			.of_match = _name,			\
343 			.regulators_node = "regulators",	\
344 			.n_voltages = ARRAY_SIZE(voltages),	\
345 			.ops = &pf8x00_vsnvs_ops,		\
346 			.type = REGULATOR_VOLTAGE,		\
347 			.id = PF8X00_VSNVS,			\
348 			.owner = THIS_MODULE,			\
349 			.volt_table = voltages,			\
350 			.vsel_reg = (base),			\
351 			.vsel_mask = 0x3,			\
352 		},						\
353 	}
354 
355 static struct pf8x00_regulator pf8x00_regulators_data[PF8X00_MAX_REGULATORS] = {
356 	PF8X00LDO(1, "ldo1", PF8X00_LDO_BASE(PF8X00_LDO1), pf8x00_ldo_voltages),
357 	PF8X00LDO(2, "ldo2", PF8X00_LDO_BASE(PF8X00_LDO2), pf8x00_ldo_voltages),
358 	PF8X00LDO(3, "ldo3", PF8X00_LDO_BASE(PF8X00_LDO3), pf8x00_ldo_voltages),
359 	PF8X00LDO(4, "ldo4", PF8X00_LDO_BASE(PF8X00_LDO4), pf8x00_ldo_voltages),
360 	PF8X00BUCK(1, "buck1", PF8X00_SW_BASE(PF8X00_BUCK1), pf8x00_sw1_to_6_voltages),
361 	PF8X00BUCK(2, "buck2", PF8X00_SW_BASE(PF8X00_BUCK2), pf8x00_sw1_to_6_voltages),
362 	PF8X00BUCK(3, "buck3", PF8X00_SW_BASE(PF8X00_BUCK3), pf8x00_sw1_to_6_voltages),
363 	PF8X00BUCK(4, "buck4", PF8X00_SW_BASE(PF8X00_BUCK4), pf8x00_sw1_to_6_voltages),
364 	PF8X00BUCK(5, "buck5", PF8X00_SW_BASE(PF8X00_BUCK5), pf8x00_sw1_to_6_voltages),
365 	PF8X00BUCK(6, "buck6", PF8X00_SW_BASE(PF8X00_BUCK6), pf8x00_sw1_to_6_voltages),
366 	PF8X00BUCK(7, "buck7", PF8X00_SW_BASE(PF8X00_BUCK7), pf8x00_sw7_voltages),
367 	PF8X00VSNVS("vsnvs", PF8X00_VSNVS_CONFIG1, pf8x00_vsnvs_voltages),
368 };
369 
370 static int pf8x00_identify(struct pf8x00_chip *chip)
371 {
372 	unsigned int value;
373 	u8 dev_fam, dev_id;
374 	const char *name = NULL;
375 	int ret;
376 
377 	ret = regmap_read(chip->regmap, PF8X00_DEVICEID, &value);
378 	if (ret) {
379 		dev_err(chip->dev, "failed to read chip family\n");
380 		return ret;
381 	}
382 
383 	dev_fam = value & PF8X00_DEVICE_FAM_MASK;
384 	switch (dev_fam) {
385 	case PF8X00_FAM:
386 		break;
387 	default:
388 		dev_err(chip->dev,
389 			"Chip 0x%x is not from PF8X00 family\n", dev_fam);
390 		return ret;
391 	}
392 
393 	dev_id = value & PF8X00_DEVICE_ID_MASK;
394 	switch (dev_id) {
395 	case PF8100:
396 		name = "PF8100";
397 		break;
398 	case PF8121A:
399 		name = "PF8121A";
400 		break;
401 	case PF8200:
402 		name = "PF8100";
403 		break;
404 	default:
405 		dev_err(chip->dev, "Unknown pf8x00 device id 0x%x\n", dev_id);
406 		return -ENODEV;
407 	}
408 
409 	dev_info(chip->dev, "%s PMIC found.\n", name);
410 
411 	return 0;
412 }
413 
414 static int pf8x00_i2c_probe(struct i2c_client *client)
415 {
416 	struct regulator_config config = { NULL, };
417 	struct pf8x00_chip *chip;
418 	int id;
419 	int ret;
420 
421 	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
422 	if (!chip)
423 		return -ENOMEM;
424 
425 	i2c_set_clientdata(client, chip);
426 	chip->dev = &client->dev;
427 
428 	chip->regmap = devm_regmap_init_i2c(client, &pf8x00_regmap_config);
429 	if (IS_ERR(chip->regmap)) {
430 		ret = PTR_ERR(chip->regmap);
431 		dev_err(&client->dev,
432 			"regmap allocation failed with err %d\n", ret);
433 		return ret;
434 	}
435 
436 	ret = pf8x00_identify(chip);
437 	if (ret)
438 		return ret;
439 
440 	for (id = 0; id < ARRAY_SIZE(pf8x00_regulators_data); id++) {
441 		struct pf8x00_regulator *data = &pf8x00_regulators_data[id];
442 		struct regulator_dev *rdev;
443 
444 		config.dev = chip->dev;
445 		config.driver_data = chip;
446 		config.regmap = chip->regmap;
447 
448 		rdev = devm_regulator_register(&client->dev, &data->desc, &config);
449 		if (IS_ERR(rdev)) {
450 			dev_err(&client->dev,
451 				"failed to register %s regulator\n", data->desc.name);
452 			return PTR_ERR(rdev);
453 		}
454 
455 		if ((id >= PF8X00_BUCK1) && (id <= PF8X00_BUCK7)) {
456 			u8 reg = PF8X00_SW_BASE(id) + SW_CONFIG2;
457 
458 			regmap_update_bits(chip->regmap, reg,
459 					   PF8X00_SWXPHASE_MASK,
460 					   data->phase_shift);
461 
462 			regmap_update_bits(chip->regmap, reg,
463 					   PF8X00_SWXILIM_MASK,
464 					   data->ilim << PF8X00_SWXILIM_SHIFT);
465 		}
466 	}
467 
468 	return 0;
469 }
470 
471 static const struct of_device_id pf8x00_dt_ids[] = {
472 	{ .compatible = "nxp,pf8x00",},
473 	{ }
474 };
475 MODULE_DEVICE_TABLE(of, pf8x00_dt_ids);
476 
477 static const struct i2c_device_id pf8x00_i2c_id[] = {
478 	{ "pf8x00", 0 },
479 	{},
480 };
481 MODULE_DEVICE_TABLE(i2c, pf8x00_i2c_id);
482 
483 static struct i2c_driver pf8x00_regulator_driver = {
484 	.id_table = pf8x00_i2c_id,
485 	.driver = {
486 		.name = "pf8x00",
487 		.of_match_table = pf8x00_dt_ids,
488 	},
489 	.probe_new = pf8x00_i2c_probe,
490 };
491 module_i2c_driver(pf8x00_regulator_driver);
492 
493 MODULE_AUTHOR("Jagan Teki <jagan@amarulasolutions.com>");
494 MODULE_AUTHOR("Troy Kisky <troy.kisky@boundarydevices.com>");
495 MODULE_DESCRIPTION("Regulator Driver for NXP's PF8100/PF8121A/PF8200 PMIC");
496 MODULE_LICENSE("GPL v2");
497