1// SPDX-License-Identifier: GPL-2.0
2// Copyright 2025 NXP.
3// NXP PF0900 pmic driver
4
5#include <linux/bitfield.h>
6#include <linux/crc8.h>
7#include <linux/err.h>
8#include <linux/gpio/consumer.h>
9#include <linux/i2c.h>
10#include <linux/interrupt.h>
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/of.h>
14#include <linux/of_device.h>
15#include <linux/platform_device.h>
16#include <linux/regmap.h>
17#include <linux/regulator/driver.h>
18#include <linux/regulator/machine.h>
19#include <linux/regulator/of_regulator.h>
20
21enum pf0900_regulators {
22 PF0900_SW1 = 0,
23 PF0900_SW2,
24 PF0900_SW3,
25 PF0900_SW4,
26 PF0900_SW5,
27 PF0900_LDO1,
28 PF0900_LDO2,
29 PF0900_LDO3,
30 PF0900_VAON,
31 PF0900_REGULATOR_CNT,
32};
33
34enum {
35 PF0900_DVS_LEVEL_RUN = 0,
36 PF0900_DVS_LEVEL_STANDBY,
37 PF0900_DVS_LEVEL_MAX,
38};
39
40
41#define PF0900_VAON_VOLTAGE_NUM 0x03
42#define PF0900_SW_VOLTAGE_NUM 0x100
43#define PF0900_LDO_VOLTAGE_NUM 0x20
44
45#define REGU_SW_CNT 0x5
46#define REGU_LDO_VAON_CNT 0x4
47
48enum {
49 PF0900_REG_DEV_ID = 0x00,
50 PF0900_REG_DEV_FAM = 0x01,
51 PF0900_REG_REV_ID = 0x02,
52 PF0900_REG_PROG_ID1 = 0x03,
53 PF0900_REG_PROG_ID2 = 0x04,
54 PF0900_REG_SYSTEM_INT = 0x05,
55 PF0900_REG_STATUS1_INT = 0x06,
56 PF0900_REG_STATUS1_MSK = 0x07,
57 PF0900_REG_STATUS1_SNS = 0x08,
58 PF0900_REG_STATUS2_INT = 0x09,
59 PF0900_REG_STATUS2_MSK = 0x0A,
60 PF0900_REG_STATUS2_SNS = 0x0B,
61 PF0900_REG_STATUS3_INT = 0x0C,
62 PF0900_REG_STATUS3_MSK = 0x0D,
63 PF0900_REG_SW_MODE_INT = 0x0E,
64 PF0900_REG_SW_MODE_MSK = 0x0F,
65 PF0900_REG_SW_ILIM_INT = 0x10,
66 PF0900_REG_SW_ILIM_MSK = 0x11,
67 PF0900_REG_SW_ILIM_SNS = 0x12,
68 PF0900_REG_LDO_ILIM_INT = 0x13,
69 PF0900_REG_LDO_ILIM_MSK = 0x14,
70 PF0900_REG_LDO_ILIM_SNS = 0x15,
71 PF0900_REG_SW_UV_INT = 0x16,
72 PF0900_REG_SW_UV_MSK = 0x17,
73 PF0900_REG_SW_UV_SNS = 0x18,
74 PF0900_REG_SW_OV_INT = 0x19,
75 PF0900_REG_SW_OV_MSK = 0x1A,
76 PF0900_REG_SW_OV_SNS = 0x1B,
77 PF0900_REG_LDO_UV_INT = 0x1C,
78 PF0900_REG_LDO_UV_MSK = 0x1D,
79 PF0900_REG_LDO_UV_SNS = 0x1E,
80 PF0900_REG_LDO_OV_INT = 0x1F,
81 PF0900_REG_LDO_OV_MSK = 0x20,
82 PF0900_REG_LDO_OV_SNS = 0x21,
83 PF0900_REG_PWRON_INT = 0x22,
84 PF0900_REG_IO_INT = 0x24,
85 PF0900_REG_IO_MSK = 0x25,
86 PF0900_REG_IO_SNS = 0x26,
87 PF0900_REG_IOSHORT_SNS = 0x27,
88 PF0900_REG_ABIST_OV1 = 0x28,
89 PF0900_REG_ABIST_OV2 = 0x29,
90 PF0900_REG_ABIST_UV1 = 0x2A,
91 PF0900_REG_ABIST_UV2 = 0x2B,
92 PF0900_REG_ABIST_IO = 0x2C,
93 PF0900_REG_TEST_FLAGS = 0x2D,
94 PF0900_REG_HFAULT_FLAGS = 0x2E,
95 PF0900_REG_FAULT_FLAGS = 0x2F,
96 PF0900_REG_FS0B_CFG = 0x30,
97 PF0900_REG_FCCU_CFG = 0x31,
98 PF0900_REG_RSTB_CFG1 = 0x32,
99 PF0900_REG_SYSTEM_CMD = 0x33,
100 PF0900_REG_FS0B_CMD = 0x34,
101 PF0900_REG_SECURE_WR1 = 0x35,
102 PF0900_REG_SECURE_WR2 = 0x36,
103 PF0900_REG_VMON_CFG1 = 0x37,
104 PF0900_REG_SYS_CFG1 = 0x38,
105 PF0900_REG_GPO_CFG = 0x39,
106 PF0900_REG_GPO_CTRL = 0x3A,
107 PF0900_REG_PWRUP_CFG = 0x3B,
108 PF0900_REG_RSTB_PWRUP = 0x3C,
109 PF0900_REG_GPIO1_PWRUP = 0x3D,
110 PF0900_REG_GPIO2_PWRUP = 0x3E,
111 PF0900_REG_GPIO3_PWRUP = 0x3F,
112 PF0900_REG_GPIO4_PWRUP = 0x40,
113 PF0900_REG_VMON1_PWRUP = 0x41,
114 PF0900_REG_VMON2_PWRUP = 0x42,
115 PF0900_REG_SW1_PWRUP = 0x43,
116 PF0900_REG_SW2_PWRUP = 0x44,
117 PF0900_REG_SW3_PWRUP = 0x45,
118 PF0900_REG_SW4_PWRUP = 0x46,
119 PF0900_REG_SW5_PWRUP = 0x47,
120 PF0900_REG_LDO1_PWRUP = 0x48,
121 PF0900_REG_LDO2_PWRUP = 0x49,
122 PF0900_REG_LDO3_PWRUP = 0x4A,
123 PF0900_REG_VAON_PWRUP = 0x4B,
124 PF0900_REG_FREQ_CTRL = 0x4C,
125 PF0900_REG_PWRON_CFG = 0x4D,
126 PF0900_REG_WD_CTRL1 = 0x4E,
127 PF0900_REG_WD_CTRL2 = 0x4F,
128 PF0900_REG_WD_CFG1 = 0x50,
129 PF0900_REG_WD_CFG2 = 0x51,
130 PF0900_REG_WD_CNT1 = 0x52,
131 PF0900_REG_WD_CNT2 = 0x53,
132 PF0900_REG_FAULT_CFG = 0x54,
133 PF0900_REG_FAULT_CNT = 0x55,
134 PF0900_REG_DFS_CNT = 0x56,
135 PF0900_REG_AMUX_CFG = 0x57,
136 PF0900_REG_VMON1_RUN_CFG = 0x58,
137 PF0900_REG_VMON1_STBY_CFG = 0x59,
138 PF0900_REG_VMON1_CTRL = 0x5A,
139 PF0900_REG_VMON2_RUN_CFG = 0x5B,
140 PF0900_REG_VMON2_STBY_CFG = 0x5C,
141 PF0900_REG_VMON2_CTRL = 0x5D,
142 PF0900_REG_SW1_VRUN = 0x5E,
143 PF0900_REG_SW1_VSTBY = 0x5F,
144 PF0900_REG_SW1_MODE = 0x60,
145 PF0900_REG_SW1_CFG1 = 0x61,
146 PF0900_REG_SW1_CFG2 = 0x62,
147 PF0900_REG_SW2_VRUN = 0x63,
148 PF0900_REG_SW2_VSTBY = 0x64,
149 PF0900_REG_SW2_MODE = 0x65,
150 PF0900_REG_SW2_CFG1 = 0x66,
151 PF0900_REG_SW2_CFG2 = 0x67,
152 PF0900_REG_SW3_VRUN = 0x68,
153 PF0900_REG_SW3_VSTBY = 0x69,
154 PF0900_REG_SW3_MODE = 0x6A,
155 PF0900_REG_SW3_CFG1 = 0x6B,
156 PF0900_REG_SW3_CFG2 = 0x6C,
157 PF0900_REG_SW4_VRUN = 0x6D,
158 PF0900_REG_SW4_VSTBY = 0x6E,
159 PF0900_REG_SW4_MODE = 0x6F,
160 PF0900_REG_SW4_CFG1 = 0x70,
161 PF0900_REG_SW4_CFG2 = 0x71,
162 PF0900_REG_SW5_VRUN = 0x72,
163 PF0900_REG_SW5_VSTBY = 0x73,
164 PF0900_REG_SW5_MODE = 0x74,
165 PF0900_REG_SW5_CFG1 = 0x75,
166 PF0900_REG_SW5_CFG2 = 0x76,
167 PF0900_REG_LDO1_RUN = 0x77,
168 PF0900_REG_LDO1_STBY = 0x78,
169 PF0900_REG_LDO1_CFG2 = 0x79,
170 PF0900_REG_LDO2_RUN = 0x7A,
171 PF0900_REG_LDO2_STBY = 0x7B,
172 PF0900_REG_LDO2_CFG2 = 0x7C,
173 PF0900_REG_LDO3_RUN = 0x7D,
174 PF0900_REG_LDO3_STBY = 0x7E,
175 PF0900_REG_LDO3_CFG2 = 0x7F,
176 PF0900_REG_VAON_CFG1 = 0x80,
177 PF0900_REG_VAON_CFG2 = 0x81,
178 PF0900_REG_SYS_DIAG = 0x82,
179 PF0900_MAX_REGISTER,
180};
181
182/* PF0900 SW MODE */
183#define SW_RUN_MODE_OFF 0x00
184#define SW_RUN_MODE_PWM 0x01
185#define SW_RUN_MODE_PFM 0x02
186#define SW_STBY_MODE_OFF 0x00
187#define SW_STBY_MODE_PWM 0x04
188#define SW_STBY_MODE_PFM 0x08
189
190/* PF0900 SW MODE MASK */
191#define SW_RUN_MODE_MASK GENMASK(1, 0)
192#define SW_STBY_MODE_MASK GENMASK(3, 2)
193
194/* PF0900 SW VRUN/VSTBY MASK */
195#define PF0900_SW_VOL_MASK GENMASK(7, 0)
196
197/* PF0900_REG_VAON_CFG1 bits */
198#define PF0900_VAON_1P8V 0x01
199
200#define PF0900_VAON_MASK GENMASK(1, 0)
201
202/* PF0900_REG_SWX_CFG1 MASK */
203#define PF0900_SW_DVS_MASK GENMASK(4, 3)
204
205/* PF0900_REG_LDO_RUN MASK */
206#define VLDO_RUN_MASK GENMASK(4, 0)
207#define LDO_RUN_EN_MASK BIT(5)
208
209/* PF0900_REG_STATUS1_INT bits */
210#define PF0900_IRQ_PWRUP BIT(3)
211
212/* PF0900_REG_ILIM_INT bits */
213#define PF0900_IRQ_SW1_IL BIT(0)
214#define PF0900_IRQ_SW2_IL BIT(1)
215#define PF0900_IRQ_SW3_IL BIT(2)
216#define PF0900_IRQ_SW4_IL BIT(3)
217#define PF0900_IRQ_SW5_IL BIT(4)
218
219#define PF0900_IRQ_LDO1_IL BIT(0)
220#define PF0900_IRQ_LDO2_IL BIT(1)
221#define PF0900_IRQ_LDO3_IL BIT(2)
222
223/* PF0900_REG_UV_INT bits */
224#define PF0900_IRQ_SW1_UV BIT(0)
225#define PF0900_IRQ_SW2_UV BIT(1)
226#define PF0900_IRQ_SW3_UV BIT(2)
227#define PF0900_IRQ_SW4_UV BIT(3)
228#define PF0900_IRQ_SW5_UV BIT(4)
229
230#define PF0900_IRQ_LDO1_UV BIT(0)
231#define PF0900_IRQ_LDO2_UV BIT(1)
232#define PF0900_IRQ_LDO3_UV BIT(2)
233#define PF0900_IRQ_VAON_UV BIT(3)
234
235/* PF0900_REG_OV_INT bits */
236#define PF0900_IRQ_SW1_OV BIT(0)
237#define PF0900_IRQ_SW2_OV BIT(1)
238#define PF0900_IRQ_SW3_OV BIT(2)
239#define PF0900_IRQ_SW4_OV BIT(3)
240#define PF0900_IRQ_SW5_OV BIT(4)
241
242#define PF0900_IRQ_LDO1_OV BIT(0)
243#define PF0900_IRQ_LDO2_OV BIT(1)
244#define PF0900_IRQ_LDO3_OV BIT(2)
245#define PF0900_IRQ_VAON_OV BIT(3)
246
247struct pf0900_regulator_desc {
248 struct regulator_desc desc;
249 unsigned int suspend_enable_mask;
250 unsigned int suspend_voltage_reg;
251 unsigned int suspend_voltage_cache;
252};
253
254struct pf0900_drvdata {
255 const struct pf0900_regulator_desc *desc;
256 unsigned int rcnt;
257};
258
259struct pf0900 {
260 struct device *dev;
261 struct regmap *regmap;
262 const struct pf0900_drvdata *drvdata;
263 struct regulator_dev *rdevs[PF0900_REGULATOR_CNT];
264 int irq;
265 unsigned short addr;
266 bool crc_en;
267};
268
269enum pf0900_regulator_type {
270 PF0900_SW = 0,
271 PF0900_LDO,
272};
273
274#define PF0900_REGU_IRQ(_reg, _type, _event) \
275 { \
276 .reg = _reg, \
277 .type = _type, \
278 .event = _event, \
279 }
280
281struct pf0900_regulator_irq {
282 unsigned int reg;
283 unsigned int type;
284 unsigned int event;
285};
286
287static const struct regmap_range pf0900_range = {
288 .range_min = PF0900_REG_DEV_ID,
289 .range_max = PF0900_REG_SYS_DIAG,
290};
291
292static const struct regmap_access_table pf0900_volatile_regs = {
293 .yes_ranges = &pf0900_range,
294 .n_yes_ranges = 1,
295};
296
297static const struct regmap_config pf0900_regmap_config = {
298 .reg_bits = 8,
299 .val_bits = 8,
300 .volatile_table = &pf0900_volatile_regs,
301 .max_register = PF0900_MAX_REGISTER - 1,
302 .cache_type = REGCACHE_MAPLE,
303};
304
305static uint8_t crc8_j1850(unsigned short addr, unsigned int reg,
306 unsigned int val)
307{
308 uint8_t crcBuf[3];
309 uint8_t t_crc;
310 uint8_t i, j;
311
312 crcBuf[0] = addr;
313 crcBuf[1] = reg;
314 crcBuf[2] = val;
315 t_crc = 0xFF;
316
317 /*
318 * The CRC calculation is based on the standard CRC-8-SAE as
319 * defined in the SAE-J1850 specification with the following
320 * characteristics.
321 * Polynomial = 0x1D
322 * Initial Value = 0xFF
323 * The CRC byte is calculated by shifting 24-bit data through
324 * the CRC polynomial.The 24-bits package is built as follows:
325 * DEVICE_ADDR[b8] + REGISTER_ADDR [b8] +DATA[b8]
326 * The DEVICE_ADDR is calculated as the 7-bit slave address
327 * shifted left one space plus the corresponding read/write bit.
328 * (7Bit Address [b7] << 1 ) + R/W = DEVICE_ADDR[b8]
329 */
330 for (i = 0; i < sizeof(crcBuf); i++) {
331 t_crc ^= crcBuf[i];
332 for (j = 0; j < 8; j++) {
333 if ((t_crc & 0x80) != 0) {
334 t_crc <<= 1;
335 t_crc ^= 0x1D;
336 } else {
337 t_crc <<= 1;
338 }
339 }
340 }
341
342 return t_crc;
343}
344
345static int pf0900_regmap_read(void *context, unsigned int reg,
346 unsigned int *val)
347{
348 struct device *dev = context;
349 struct i2c_client *i2c = to_i2c_client(dev);
350 struct pf0900 *pf0900 = dev_get_drvdata(dev);
351 int ret;
352 u8 crc;
353
354 if (!pf0900 || !pf0900->dev)
355 return -EINVAL;
356
357 if (reg >= PF0900_MAX_REGISTER) {
358 dev_err(pf0900->dev, "Invalid register address: 0x%x\n", reg);
359 return -EINVAL;
360 }
361
362 if (pf0900->crc_en) {
363 ret = i2c_smbus_read_word_data(client: i2c, command: reg);
364 if (ret < 0) {
365 dev_err(pf0900->dev, "Read error at reg=0x%x: %d\n", reg, ret);
366 return ret;
367 }
368
369 *val = (u16)ret;
370 crc = crc8_j1850(addr: pf0900->addr << 1 | 0x1, reg, FIELD_GET(GENMASK(7, 0), *val));
371 if (crc != FIELD_GET(GENMASK(15, 8), *val)) {
372 dev_err(pf0900->dev, "Crc check error!\n");
373 return -EINVAL;
374 }
375 *val = FIELD_GET(GENMASK(7, 0), *val);
376 } else {
377 ret = i2c_smbus_read_byte_data(client: i2c, command: reg);
378 if (ret < 0) {
379 dev_err(pf0900->dev, "Read error at reg=0x%x: %d\n", reg, ret);
380 return ret;
381 }
382 *val = ret;
383 }
384
385 return 0;
386}
387
388static int pf0900_regmap_write(void *context, unsigned int reg,
389 unsigned int val)
390{
391 struct device *dev = context;
392 struct i2c_client *i2c = to_i2c_client(dev);
393 struct pf0900 *pf0900 = dev_get_drvdata(dev);
394 uint8_t data[2];
395 int ret;
396
397 if (!pf0900 || !pf0900->dev)
398 return -EINVAL;
399
400 if (reg >= PF0900_MAX_REGISTER) {
401 dev_err(pf0900->dev, "Invalid register address: 0x%x\n", reg);
402 return -EINVAL;
403 }
404
405 data[0] = val;
406 if (pf0900->crc_en) {
407 /* Get CRC */
408 data[1] = crc8_j1850(addr: pf0900->addr << 1, reg, val: data[0]);
409 val = FIELD_PREP(GENMASK(15, 8), data[1]) | data[0];
410 ret = i2c_smbus_write_word_data(client: i2c, command: reg, value: val);
411 } else {
412 ret = i2c_smbus_write_byte_data(client: i2c, command: reg, value: data[0]);
413 }
414
415 if (ret) {
416 dev_err(pf0900->dev, "Write reg=0x%x error!\n", reg);
417 return ret;
418 }
419
420 return 0;
421}
422
423static int pf0900_suspend_enable(struct regulator_dev *rdev)
424{
425 struct pf0900_regulator_desc *rdata = rdev_get_drvdata(rdev);
426 struct regmap *rmap = rdev_get_regmap(rdev);
427
428 return regmap_update_bits(map: rmap, reg: rdata->desc.enable_reg,
429 mask: rdata->suspend_enable_mask, SW_STBY_MODE_PFM);
430}
431
432static int pf0900_suspend_disable(struct regulator_dev *rdev)
433{
434 struct pf0900_regulator_desc *rdata = rdev_get_drvdata(rdev);
435 struct regmap *rmap = rdev_get_regmap(rdev);
436
437 return regmap_update_bits(map: rmap, reg: rdata->desc.enable_reg,
438 mask: rdata->suspend_enable_mask, SW_STBY_MODE_OFF);
439}
440
441static int pf0900_set_suspend_voltage(struct regulator_dev *rdev, int uV)
442{
443 struct pf0900_regulator_desc *rdata = rdev_get_drvdata(rdev);
444 struct regmap *rmap = rdev_get_regmap(rdev);
445 int ret;
446
447 if (rdata->suspend_voltage_cache == uV)
448 return 0;
449
450 ret = regulator_map_voltage_iterate(rdev, min_uV: uV, max_uV: uV);
451 if (ret < 0) {
452 dev_err(rdev_get_dev(rdev), "failed to map %i uV\n", uV);
453 return ret;
454 }
455
456 dev_dbg(rdev_get_dev(rdev), "uV: %i, reg: 0x%x, msk: 0x%x, val: 0x%x\n",
457 uV, rdata->suspend_voltage_reg, rdata->desc.vsel_mask, ret);
458 ret = regmap_update_bits(map: rmap, reg: rdata->suspend_voltage_reg,
459 mask: rdata->desc.vsel_mask, val: ret);
460 if (ret < 0) {
461 dev_err(rdev_get_dev(rdev), "failed to set %i uV\n", uV);
462 return ret;
463 }
464
465 rdata->suspend_voltage_cache = uV;
466
467 return 0;
468}
469
470static const struct regmap_bus pf0900_regmap_bus = {
471 .reg_read = pf0900_regmap_read,
472 .reg_write = pf0900_regmap_write,
473};
474
475static const struct regulator_ops pf0900_avon_regulator_ops = {
476 .list_voltage = regulator_list_voltage_table,
477 .set_voltage_sel = regulator_set_voltage_sel_regmap,
478 .get_voltage_sel = regulator_get_voltage_sel_regmap,
479};
480
481static const struct regulator_ops pf0900_dvs_sw_regulator_ops = {
482 .enable = regulator_enable_regmap,
483 .disable = regulator_disable_regmap,
484 .is_enabled = regulator_is_enabled_regmap,
485 .list_voltage = regulator_list_voltage_linear_range,
486 .set_voltage_sel = regulator_set_voltage_sel_regmap,
487 .get_voltage_sel = regulator_get_voltage_sel_regmap,
488 .set_voltage_time_sel = regulator_set_voltage_time_sel,
489 .set_ramp_delay = regulator_set_ramp_delay_regmap,
490 .set_suspend_enable = pf0900_suspend_enable,
491 .set_suspend_disable = pf0900_suspend_disable,
492 .set_suspend_voltage = pf0900_set_suspend_voltage,
493};
494
495static const struct regulator_ops pf0900_ldo_regulator_ops = {
496 .enable = regulator_enable_regmap,
497 .disable = regulator_disable_regmap,
498 .is_enabled = regulator_is_enabled_regmap,
499 .list_voltage = regulator_list_voltage_linear_range,
500 .set_voltage_sel = regulator_set_voltage_sel_regmap,
501 .get_voltage_sel = regulator_get_voltage_sel_regmap,
502};
503
504/*
505 * SW1/2/3/4/5
506 * SW1_DVS[1:0] SW1 DVS ramp rate setting
507 * 00: 15.6mV/8usec
508 * 01: 15.6mV/4usec
509 * 10: 15.6mV/2usec
510 * 11: 15.6mV/1usec
511 */
512static const unsigned int pf0900_dvs_sw_ramp_table[] = {
513 1950, 3900, 7800, 15600
514};
515
516/* VAON 1.8V, 3.0V, or 3.3V */
517static const int pf0900_vaon_voltages[] = {
518 0, 1800000, 3000000, 3300000,
519};
520
521/*
522 * SW1 0.5V to 3.3V
523 * 0.5V to 1.35V (6.25mV step)
524 * 1.8V to 2.5V (125mV step)
525 * 2.8V to 3.3V (250mV step)
526 */
527static const struct linear_range pf0900_dvs_sw1_volts[] = {
528 REGULATOR_LINEAR_RANGE(0, 0x00, 0x08, 0),
529 REGULATOR_LINEAR_RANGE(500000, 0x09, 0x91, 6250),
530 REGULATOR_LINEAR_RANGE(0, 0x92, 0x9E, 0),
531 REGULATOR_LINEAR_RANGE(1500000, 0x9F, 0x9F, 0),
532 REGULATOR_LINEAR_RANGE(1800000, 0xA0, 0xD8, 12500),
533 REGULATOR_LINEAR_RANGE(0, 0xD9, 0xDF, 0),
534 REGULATOR_LINEAR_RANGE(2800000, 0xE0, 0xF4, 25000),
535 REGULATOR_LINEAR_RANGE(0, 0xF5, 0xFF, 0),
536};
537
538/*
539 * SW2/3/4/5 0.3V to 3.3V
540 * 0.45V to 1.35V (6.25mV step)
541 * 1.8V to 2.5V (125mV step)
542 * 2.8V to 3.3V (250mV step)
543 */
544static const struct linear_range pf0900_dvs_sw2345_volts[] = {
545 REGULATOR_LINEAR_RANGE(300000, 0x00, 0x00, 0),
546 REGULATOR_LINEAR_RANGE(450000, 0x01, 0x91, 6250),
547 REGULATOR_LINEAR_RANGE(0, 0x92, 0x9E, 0),
548 REGULATOR_LINEAR_RANGE(1500000, 0x9F, 0x9F, 0),
549 REGULATOR_LINEAR_RANGE(1800000, 0xA0, 0xD8, 12500),
550 REGULATOR_LINEAR_RANGE(0, 0xD9, 0xDF, 0),
551 REGULATOR_LINEAR_RANGE(2800000, 0xE0, 0xF4, 25000),
552 REGULATOR_LINEAR_RANGE(0, 0xF5, 0xFF, 0),
553};
554
555/*
556 * LDO1
557 * 0.75V to 3.3V
558 */
559static const struct linear_range pf0900_ldo1_volts[] = {
560 REGULATOR_LINEAR_RANGE(750000, 0x00, 0x0F, 50000),
561 REGULATOR_LINEAR_RANGE(1800000, 0x10, 0x1F, 100000),
562};
563
564/*
565 * LDO2/3
566 * 0.65V to 3.3V (50mV step)
567 */
568static const struct linear_range pf0900_ldo23_volts[] = {
569 REGULATOR_LINEAR_RANGE(650000, 0x00, 0x0D, 50000),
570 REGULATOR_LINEAR_RANGE(1400000, 0x0E, 0x0F, 100000),
571 REGULATOR_LINEAR_RANGE(1800000, 0x10, 0x1F, 100000),
572};
573
574static const struct pf0900_regulator_desc pf0900_regulators[] = {
575 {
576 .desc = {
577 .name = "sw1",
578 .of_match = of_match_ptr("sw1"),
579 .regulators_node = of_match_ptr("regulators"),
580 .id = PF0900_SW1,
581 .ops = &pf0900_dvs_sw_regulator_ops,
582 .type = REGULATOR_VOLTAGE,
583 .n_voltages = PF0900_SW_VOLTAGE_NUM,
584 .linear_ranges = pf0900_dvs_sw1_volts,
585 .n_linear_ranges = ARRAY_SIZE(pf0900_dvs_sw1_volts),
586 .vsel_reg = PF0900_REG_SW1_VRUN,
587 .vsel_mask = PF0900_SW_VOL_MASK,
588 .enable_reg = PF0900_REG_SW1_MODE,
589 .enable_mask = SW_RUN_MODE_MASK,
590 .enable_val = SW_RUN_MODE_PWM,
591 .ramp_reg = PF0900_REG_SW1_CFG1,
592 .ramp_mask = PF0900_SW_DVS_MASK,
593 .ramp_delay_table = pf0900_dvs_sw_ramp_table,
594 .n_ramp_values = ARRAY_SIZE(pf0900_dvs_sw_ramp_table),
595 .owner = THIS_MODULE,
596 },
597 .suspend_enable_mask = SW_STBY_MODE_MASK,
598 .suspend_voltage_reg = PF0900_REG_SW1_VSTBY,
599 },
600 {
601 .desc = {
602 .name = "sw2",
603 .of_match = of_match_ptr("sw2"),
604 .regulators_node = of_match_ptr("regulators"),
605 .id = PF0900_SW2,
606 .ops = &pf0900_dvs_sw_regulator_ops,
607 .type = REGULATOR_VOLTAGE,
608 .n_voltages = PF0900_SW_VOLTAGE_NUM,
609 .linear_ranges = pf0900_dvs_sw2345_volts,
610 .n_linear_ranges = ARRAY_SIZE(pf0900_dvs_sw2345_volts),
611 .vsel_reg = PF0900_REG_SW2_VRUN,
612 .vsel_mask = PF0900_SW_VOL_MASK,
613 .enable_reg = PF0900_REG_SW2_MODE,
614 .enable_mask = SW_RUN_MODE_MASK,
615 .enable_val = SW_RUN_MODE_PWM,
616 .ramp_reg = PF0900_REG_SW2_CFG1,
617 .ramp_mask = PF0900_SW_DVS_MASK,
618 .ramp_delay_table = pf0900_dvs_sw_ramp_table,
619 .n_ramp_values = ARRAY_SIZE(pf0900_dvs_sw_ramp_table),
620 .owner = THIS_MODULE,
621 },
622 .suspend_enable_mask = SW_STBY_MODE_MASK,
623 .suspend_voltage_reg = PF0900_REG_SW2_VSTBY,
624 },
625 {
626 .desc = {
627 .name = "sw3",
628 .of_match = of_match_ptr("sw3"),
629 .regulators_node = of_match_ptr("regulators"),
630 .id = PF0900_SW3,
631 .ops = &pf0900_dvs_sw_regulator_ops,
632 .type = REGULATOR_VOLTAGE,
633 .n_voltages = PF0900_SW_VOLTAGE_NUM,
634 .linear_ranges = pf0900_dvs_sw2345_volts,
635 .n_linear_ranges = ARRAY_SIZE(pf0900_dvs_sw2345_volts),
636 .vsel_reg = PF0900_REG_SW3_VRUN,
637 .vsel_mask = PF0900_SW_VOL_MASK,
638 .enable_reg = PF0900_REG_SW3_MODE,
639 .enable_mask = SW_RUN_MODE_MASK,
640 .enable_val = SW_RUN_MODE_PWM,
641 .ramp_reg = PF0900_REG_SW3_CFG1,
642 .ramp_mask = PF0900_SW_DVS_MASK,
643 .ramp_delay_table = pf0900_dvs_sw_ramp_table,
644 .n_ramp_values = ARRAY_SIZE(pf0900_dvs_sw_ramp_table),
645 .owner = THIS_MODULE,
646 },
647 .suspend_enable_mask = SW_STBY_MODE_MASK,
648 .suspend_voltage_reg = PF0900_REG_SW3_VSTBY,
649 },
650 {
651 .desc = {
652 .name = "sw4",
653 .of_match = of_match_ptr("sw4"),
654 .regulators_node = of_match_ptr("regulators"),
655 .id = PF0900_SW4,
656 .ops = &pf0900_dvs_sw_regulator_ops,
657 .type = REGULATOR_VOLTAGE,
658 .n_voltages = PF0900_SW_VOLTAGE_NUM,
659 .linear_ranges = pf0900_dvs_sw2345_volts,
660 .n_linear_ranges = ARRAY_SIZE(pf0900_dvs_sw2345_volts),
661 .vsel_reg = PF0900_REG_SW4_VRUN,
662 .vsel_mask = PF0900_SW_VOL_MASK,
663 .enable_reg = PF0900_REG_SW4_MODE,
664 .enable_mask = SW_RUN_MODE_MASK,
665 .enable_val = SW_RUN_MODE_PWM,
666 .ramp_reg = PF0900_REG_SW4_CFG1,
667 .ramp_mask = PF0900_SW_DVS_MASK,
668 .ramp_delay_table = pf0900_dvs_sw_ramp_table,
669 .n_ramp_values = ARRAY_SIZE(pf0900_dvs_sw_ramp_table),
670 .owner = THIS_MODULE,
671 },
672 .suspend_enable_mask = SW_STBY_MODE_MASK,
673 .suspend_voltage_reg = PF0900_REG_SW4_VSTBY,
674 },
675 {
676 .desc = {
677 .name = "sw5",
678 .of_match = of_match_ptr("sw5"),
679 .regulators_node = of_match_ptr("regulators"),
680 .id = PF0900_SW5,
681 .ops = &pf0900_dvs_sw_regulator_ops,
682 .type = REGULATOR_VOLTAGE,
683 .n_voltages = PF0900_SW_VOLTAGE_NUM,
684 .linear_ranges = pf0900_dvs_sw2345_volts,
685 .n_linear_ranges = ARRAY_SIZE(pf0900_dvs_sw2345_volts),
686 .vsel_reg = PF0900_REG_SW5_VRUN,
687 .vsel_mask = PF0900_SW_VOL_MASK,
688 .enable_reg = PF0900_REG_SW5_MODE,
689 .enable_mask = SW_RUN_MODE_MASK,
690 .enable_val = SW_RUN_MODE_PWM,
691 .ramp_reg = PF0900_REG_SW5_CFG1,
692 .ramp_mask = PF0900_SW_DVS_MASK,
693 .ramp_delay_table = pf0900_dvs_sw_ramp_table,
694 .n_ramp_values = ARRAY_SIZE(pf0900_dvs_sw_ramp_table),
695 .owner = THIS_MODULE,
696 },
697 .suspend_enable_mask = SW_STBY_MODE_MASK,
698 .suspend_voltage_reg = PF0900_REG_SW5_VSTBY,
699 },
700 {
701 .desc = {
702 .name = "ldo1",
703 .of_match = of_match_ptr("ldo1"),
704 .regulators_node = of_match_ptr("regulators"),
705 .id = PF0900_LDO1,
706 .ops = &pf0900_ldo_regulator_ops,
707 .type = REGULATOR_VOLTAGE,
708 .n_voltages = PF0900_LDO_VOLTAGE_NUM,
709 .linear_ranges = pf0900_ldo1_volts,
710 .n_linear_ranges = ARRAY_SIZE(pf0900_ldo1_volts),
711 .vsel_reg = PF0900_REG_LDO1_RUN,
712 .vsel_mask = VLDO_RUN_MASK,
713 .enable_reg = PF0900_REG_LDO1_RUN,
714 .enable_mask = LDO_RUN_EN_MASK,
715 .owner = THIS_MODULE,
716 },
717 },
718 {
719 .desc = {
720 .name = "ldo2",
721 .of_match = of_match_ptr("ldo2"),
722 .regulators_node = of_match_ptr("regulators"),
723 .id = PF0900_LDO2,
724 .ops = &pf0900_ldo_regulator_ops,
725 .type = REGULATOR_VOLTAGE,
726 .n_voltages = PF0900_LDO_VOLTAGE_NUM,
727 .linear_ranges = pf0900_ldo23_volts,
728 .n_linear_ranges = ARRAY_SIZE(pf0900_ldo23_volts),
729 .vsel_reg = PF0900_REG_LDO2_RUN,
730 .vsel_mask = VLDO_RUN_MASK,
731 .enable_reg = PF0900_REG_LDO2_RUN,
732 .enable_mask = LDO_RUN_EN_MASK,
733 .owner = THIS_MODULE,
734 },
735 },
736 {
737 .desc = {
738 .name = "ldo3",
739 .of_match = of_match_ptr("ldo3"),
740 .regulators_node = of_match_ptr("regulators"),
741 .id = PF0900_LDO3,
742 .ops = &pf0900_ldo_regulator_ops,
743 .type = REGULATOR_VOLTAGE,
744 .n_voltages = PF0900_LDO_VOLTAGE_NUM,
745 .linear_ranges = pf0900_ldo23_volts,
746 .n_linear_ranges = ARRAY_SIZE(pf0900_ldo23_volts),
747 .vsel_reg = PF0900_REG_LDO3_RUN,
748 .vsel_mask = VLDO_RUN_MASK,
749 .enable_reg = PF0900_REG_LDO3_RUN,
750 .enable_mask = LDO_RUN_EN_MASK,
751 .owner = THIS_MODULE,
752 },
753 },
754 {
755 .desc = {
756 .name = "vaon",
757 .of_match = of_match_ptr("vaon"),
758 .regulators_node = of_match_ptr("regulators"),
759 .id = PF0900_VAON,
760 .ops = &pf0900_avon_regulator_ops,
761 .type = REGULATOR_VOLTAGE,
762 .n_voltages = PF0900_VAON_VOLTAGE_NUM,
763 .volt_table = pf0900_vaon_voltages,
764 .enable_reg = PF0900_REG_VAON_CFG1,
765 .enable_mask = PF0900_VAON_MASK,
766 .enable_val = PF0900_VAON_1P8V,
767 .vsel_reg = PF0900_REG_VAON_CFG1,
768 .vsel_mask = PF0900_VAON_MASK,
769 .owner = THIS_MODULE,
770 },
771 },
772};
773
774struct pf0900_regulator_irq regu_irqs[] = {
775 PF0900_REGU_IRQ(PF0900_REG_SW_ILIM_INT, PF0900_SW, REGULATOR_ERROR_OVER_CURRENT_WARN),
776 PF0900_REGU_IRQ(PF0900_REG_LDO_ILIM_INT, PF0900_LDO, REGULATOR_ERROR_OVER_CURRENT_WARN),
777 PF0900_REGU_IRQ(PF0900_REG_SW_UV_INT, PF0900_SW, REGULATOR_ERROR_UNDER_VOLTAGE_WARN),
778 PF0900_REGU_IRQ(PF0900_REG_LDO_UV_INT, PF0900_LDO, REGULATOR_ERROR_UNDER_VOLTAGE_WARN),
779 PF0900_REGU_IRQ(PF0900_REG_SW_OV_INT, PF0900_SW, REGULATOR_ERROR_OVER_VOLTAGE_WARN),
780 PF0900_REGU_IRQ(PF0900_REG_LDO_OV_INT, PF0900_LDO, REGULATOR_ERROR_OVER_VOLTAGE_WARN),
781};
782
783static irqreturn_t pf0900_irq_handler(int irq, void *data)
784{
785 unsigned int val, regu, i, index;
786 struct pf0900 *pf0900 = data;
787 int ret;
788
789 for (i = 0; i < ARRAY_SIZE(regu_irqs); i++) {
790 ret = regmap_read(map: pf0900->regmap, reg: regu_irqs[i].reg, val: &val);
791 if (ret < 0) {
792 dev_err(pf0900->dev, "Failed to read %d\n", ret);
793 return IRQ_NONE;
794 }
795 if (val) {
796 ret = regmap_write_bits(map: pf0900->regmap, reg: regu_irqs[i].reg, mask: val, val);
797 if (ret < 0) {
798 dev_err(pf0900->dev, "Failed to update %d\n", ret);
799 return IRQ_NONE;
800 }
801
802 if (regu_irqs[i].type == PF0900_SW) {
803 for (index = 0; index < REGU_SW_CNT; index++) {
804 if (val & BIT(index)) {
805 regu = (enum pf0900_regulators)index;
806 regulator_notifier_call_chain(rdev: pf0900->rdevs[regu],
807 event: regu_irqs[i].event,
808 NULL);
809 }
810 }
811 } else if (regu_irqs[i].type == PF0900_LDO) {
812 for (index = 0; index < REGU_LDO_VAON_CNT; index++) {
813 if (val & BIT(index)) {
814 regu = (enum pf0900_regulators)index + PF0900_LDO1;
815 regulator_notifier_call_chain(rdev: pf0900->rdevs[regu],
816 event: regu_irqs[i].event,
817 NULL);
818 }
819 }
820 }
821 }
822 }
823
824 return IRQ_HANDLED;
825}
826
827static int pf0900_i2c_probe(struct i2c_client *i2c)
828{
829 const struct pf0900_regulator_desc *regulator_desc;
830 const struct pf0900_drvdata *drvdata = NULL;
831 struct device_node *np = i2c->dev.of_node;
832 unsigned int device_id, device_fam, i;
833 struct regulator_config config = { };
834 struct pf0900 *pf0900;
835 int ret;
836
837 if (!i2c->irq)
838 return dev_err_probe(dev: &i2c->dev, err: -EINVAL, fmt: "No IRQ configured?\n");
839
840 pf0900 = devm_kzalloc(dev: &i2c->dev, size: sizeof(struct pf0900), GFP_KERNEL);
841 if (!pf0900)
842 return -ENOMEM;
843
844 drvdata = device_get_match_data(dev: &i2c->dev);
845 if (!drvdata)
846 return dev_err_probe(dev: &i2c->dev, err: -EINVAL, fmt: "unable to find driver data\n");
847
848 regulator_desc = drvdata->desc;
849 pf0900->drvdata = drvdata;
850 pf0900->crc_en = of_property_read_bool(np, propname: "nxp,i2c-crc-enable");
851 pf0900->irq = i2c->irq;
852 pf0900->dev = &i2c->dev;
853 pf0900->addr = i2c->addr;
854
855 dev_set_drvdata(dev: &i2c->dev, data: pf0900);
856
857 pf0900->regmap = devm_regmap_init(&i2c->dev, &pf0900_regmap_bus, &i2c->dev,
858 &pf0900_regmap_config);
859 if (IS_ERR(ptr: pf0900->regmap))
860 return dev_err_probe(dev: &i2c->dev, err: PTR_ERR(ptr: pf0900->regmap),
861 fmt: "regmap initialization failed\n");
862 ret = regmap_read(map: pf0900->regmap, reg: PF0900_REG_DEV_ID, val: &device_id);
863 if (ret)
864 return dev_err_probe(dev: &i2c->dev, err: ret, fmt: "Read device id error\n");
865
866 ret = regmap_read(map: pf0900->regmap, reg: PF0900_REG_DEV_FAM, val: &device_fam);
867 if (ret)
868 return dev_err_probe(dev: &i2c->dev, err: ret, fmt: "Read device fam error\n");
869
870 /* Check your board and dts for match the right pmic */
871 if (device_fam == 0x09 && (device_id & 0x1F) != 0x0)
872 return dev_err_probe(dev: &i2c->dev, err: -EINVAL, fmt: "Device id(%x) mismatched\n",
873 device_id >> 4);
874
875 for (i = 0; i < drvdata->rcnt; i++) {
876 const struct regulator_desc *desc;
877 const struct pf0900_regulator_desc *r;
878
879 r = &regulator_desc[i];
880 desc = &r->desc;
881 config.regmap = pf0900->regmap;
882 config.driver_data = (void *)r;
883 config.dev = pf0900->dev;
884
885 pf0900->rdevs[i] = devm_regulator_register(dev: pf0900->dev, regulator_desc: desc, config: &config);
886 if (IS_ERR(ptr: pf0900->rdevs[i]))
887 return dev_err_probe(dev: pf0900->dev, err: PTR_ERR(ptr: pf0900->rdevs[i]),
888 fmt: "Failed to register regulator(%s)\n", desc->name);
889 }
890
891 ret = devm_request_threaded_irq(dev: pf0900->dev, irq: pf0900->irq, NULL,
892 thread_fn: pf0900_irq_handler,
893 irqflags: (IRQF_TRIGGER_FALLING | IRQF_ONESHOT),
894 devname: "pf0900-irq", dev_id: pf0900);
895
896 if (ret != 0)
897 return dev_err_probe(dev: pf0900->dev, err: ret, fmt: "Failed to request IRQ: %d\n",
898 pf0900->irq);
899 /*
900 * The PWRUP_M is unmasked by default. When the device enter in RUN state,
901 * it will assert the PWRUP_I interrupt and assert the INTB pin to inform
902 * the MCU that it has finished the power up sequence properly.
903 */
904 ret = regmap_write_bits(map: pf0900->regmap, reg: PF0900_REG_STATUS1_INT, PF0900_IRQ_PWRUP,
905 PF0900_IRQ_PWRUP);
906 if (ret)
907 return dev_err_probe(dev: &i2c->dev, err: ret, fmt: "Clean PWRUP_I error\n");
908
909 /* mask interrupt PWRUP */
910 ret = regmap_update_bits(map: pf0900->regmap, reg: PF0900_REG_STATUS1_MSK, PF0900_IRQ_PWRUP,
911 PF0900_IRQ_PWRUP);
912 if (ret)
913 return dev_err_probe(dev: &i2c->dev, err: ret, fmt: "Unmask irq error\n");
914
915 ret = regmap_update_bits(map: pf0900->regmap, reg: PF0900_REG_SW_ILIM_MSK, PF0900_IRQ_SW1_IL |
916 PF0900_IRQ_SW2_IL | PF0900_IRQ_SW3_IL | PF0900_IRQ_SW4_IL |
917 PF0900_IRQ_SW5_IL, val: 0);
918 if (ret)
919 return dev_err_probe(dev: &i2c->dev, err: ret, fmt: "Unmask irq error\n");
920
921 ret = regmap_update_bits(map: pf0900->regmap, reg: PF0900_REG_SW_UV_MSK, PF0900_IRQ_SW1_UV |
922 PF0900_IRQ_SW2_UV | PF0900_IRQ_SW3_UV | PF0900_IRQ_SW4_UV |
923 PF0900_IRQ_SW5_UV, val: 0);
924 if (ret)
925 return dev_err_probe(dev: &i2c->dev, err: ret, fmt: "Unmask irq error\n");
926
927 ret = regmap_update_bits(map: pf0900->regmap, reg: PF0900_REG_SW_OV_MSK, PF0900_IRQ_SW1_OV |
928 PF0900_IRQ_SW2_OV | PF0900_IRQ_SW3_OV | PF0900_IRQ_SW4_OV |
929 PF0900_IRQ_SW5_OV, val: 0);
930 if (ret)
931 return dev_err_probe(dev: &i2c->dev, err: ret, fmt: "Unmask irq error\n");
932
933 ret = regmap_update_bits(map: pf0900->regmap, reg: PF0900_REG_LDO_ILIM_MSK, PF0900_IRQ_LDO1_IL |
934 PF0900_IRQ_LDO2_IL | PF0900_IRQ_LDO3_IL, val: 0);
935 if (ret)
936 return dev_err_probe(dev: &i2c->dev, err: ret, fmt: "Unmask irq error\n");
937
938 ret = regmap_update_bits(map: pf0900->regmap, reg: PF0900_REG_LDO_UV_MSK, PF0900_IRQ_LDO1_UV |
939 PF0900_IRQ_LDO2_UV | PF0900_IRQ_LDO3_UV | PF0900_IRQ_VAON_UV, val: 0);
940 if (ret)
941 return dev_err_probe(dev: &i2c->dev, err: ret, fmt: "Unmask irq error\n");
942
943 ret = regmap_update_bits(map: pf0900->regmap, reg: PF0900_REG_LDO_OV_MSK, PF0900_IRQ_LDO1_OV |
944 PF0900_IRQ_LDO2_OV | PF0900_IRQ_LDO3_OV | PF0900_IRQ_VAON_OV, val: 0);
945 if (ret)
946 return dev_err_probe(dev: &i2c->dev, err: ret, fmt: "Unmask irq error\n");
947
948 return 0;
949}
950
951static struct pf0900_drvdata pf0900_drvdata = {
952 .desc = pf0900_regulators,
953 .rcnt = ARRAY_SIZE(pf0900_regulators),
954};
955
956static const struct of_device_id pf0900_of_match[] = {
957 { .compatible = "nxp,pf0900", .data = &pf0900_drvdata},
958 { }
959};
960
961MODULE_DEVICE_TABLE(of, pf0900_of_match);
962
963static struct i2c_driver pf0900_i2c_driver = {
964 .driver = {
965 .name = "nxp-pf0900",
966 .of_match_table = pf0900_of_match,
967 },
968 .probe = pf0900_i2c_probe,
969};
970
971module_i2c_driver(pf0900_i2c_driver);
972
973MODULE_AUTHOR("Joy Zou <joy.zou@nxp.com>");
974MODULE_DESCRIPTION("NXP PF0900 Power Management IC driver");
975MODULE_LICENSE("GPL");
976

source code of linux/drivers/regulator/pf0900-regulator.c