File Index
Files and directories
Sign in
FILE

pf0900-regulator.c

File preview with syntax highlighting.

linux-6.19.14/drivers/regulator/pf0900-regulator.c C
  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(i2c, 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(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(i2c, 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(pf0900->addr << 1, reg, data[0]);
409		val = FIELD_PREP(GENMASK(15, 8), data[1]) | data[0];
410		ret = i2c_smbus_write_word_data(i2c, reg, val);
411	} else {
412		ret = i2c_smbus_write_byte_data(i2c, reg, 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(rmap, rdata->desc.enable_reg,
429				  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(rmap, rdata->desc.enable_reg,
438				  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, 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(rmap, rdata->suspend_voltage_reg,
459				 rdata->desc.vsel_mask, 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(pf0900->regmap, regu_irqs[i].reg, &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(pf0900->regmap, regu_irqs[i].reg, 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(pf0900->rdevs[regu],
807									      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(pf0900->rdevs[regu],
816									      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(&i2c->dev, -EINVAL, "No IRQ configured?\n");
839
840	pf0900 = devm_kzalloc(&i2c->dev, sizeof(struct pf0900), GFP_KERNEL);
841	if (!pf0900)
842		return -ENOMEM;
843
844	drvdata = device_get_match_data(&i2c->dev);
845	if (!drvdata)
846		return dev_err_probe(&i2c->dev, -EINVAL, "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, "nxp,i2c-crc-enable");
851	pf0900->irq = i2c->irq;
852	pf0900->dev = &i2c->dev;
853	pf0900->addr = i2c->addr;
854
855	dev_set_drvdata(&i2c->dev, pf0900);
856
857	pf0900->regmap = devm_regmap_init(&i2c->dev, &pf0900_regmap_bus, &i2c->dev,
858					       &pf0900_regmap_config);
859	if (IS_ERR(pf0900->regmap))
860		return dev_err_probe(&i2c->dev, PTR_ERR(pf0900->regmap),
861				     "regmap initialization failed\n");
862	ret = regmap_read(pf0900->regmap, PF0900_REG_DEV_ID, &device_id);
863	if (ret)
864		return dev_err_probe(&i2c->dev, ret, "Read device id error\n");
865
866	ret = regmap_read(pf0900->regmap, PF0900_REG_DEV_FAM, &device_fam);
867	if (ret)
868		return dev_err_probe(&i2c->dev, ret, "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(&i2c->dev, -EINVAL, "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(pf0900->dev, desc, &config);
886		if (IS_ERR(pf0900->rdevs[i]))
887			return dev_err_probe(pf0900->dev, PTR_ERR(pf0900->rdevs[i]),
888					     "Failed to register regulator(%s)\n", desc->name);
889	}
890
891	ret = devm_request_threaded_irq(pf0900->dev, pf0900->irq, NULL,
892					pf0900_irq_handler,
893					(IRQF_TRIGGER_FALLING | IRQF_ONESHOT),
894					"pf0900-irq", pf0900);
895
896	if (ret != 0)
897		return dev_err_probe(pf0900->dev, ret, "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(pf0900->regmap, PF0900_REG_STATUS1_INT, PF0900_IRQ_PWRUP,
905				PF0900_IRQ_PWRUP);
906	if (ret)
907		return dev_err_probe(&i2c->dev, ret, "Clean PWRUP_I error\n");
908
909	/* mask interrupt PWRUP */
910	ret = regmap_update_bits(pf0900->regmap, PF0900_REG_STATUS1_MSK, PF0900_IRQ_PWRUP,
911				 PF0900_IRQ_PWRUP);
912	if (ret)
913		return dev_err_probe(&i2c->dev, ret, "Unmask irq error\n");
914
915	ret = regmap_update_bits(pf0900->regmap, 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, 0);
918	if (ret)
919		return dev_err_probe(&i2c->dev, ret, "Unmask irq error\n");
920
921	ret = regmap_update_bits(pf0900->regmap, 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, 0);
924	if (ret)
925		return dev_err_probe(&i2c->dev, ret, "Unmask irq error\n");
926
927	ret = regmap_update_bits(pf0900->regmap, 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, 0);
930	if (ret)
931		return dev_err_probe(&i2c->dev, ret, "Unmask irq error\n");
932
933	ret = regmap_update_bits(pf0900->regmap, PF0900_REG_LDO_ILIM_MSK, PF0900_IRQ_LDO1_IL |
934				 PF0900_IRQ_LDO2_IL | PF0900_IRQ_LDO3_IL, 0);
935	if (ret)
936		return dev_err_probe(&i2c->dev, ret, "Unmask irq error\n");
937
938	ret = regmap_update_bits(pf0900->regmap, PF0900_REG_LDO_UV_MSK, PF0900_IRQ_LDO1_UV |
939				 PF0900_IRQ_LDO2_UV | PF0900_IRQ_LDO3_UV | PF0900_IRQ_VAON_UV, 0);
940	if (ret)
941		return dev_err_probe(&i2c->dev, ret, "Unmask irq error\n");
942
943	ret = regmap_update_bits(pf0900->regmap, PF0900_REG_LDO_OV_MSK, PF0900_IRQ_LDO1_OV |
944				 PF0900_IRQ_LDO2_OV | PF0900_IRQ_LDO3_OV | PF0900_IRQ_VAON_OV, 0);
945	if (ret)
946		return dev_err_probe(&i2c->dev, ret, "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");
~/ Read-only file preview.