xref: /OK3568_Linux_fs/kernel/drivers/mfd/max77620.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Maxim MAX77620 MFD Driver
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Author:
8*4882a593Smuzhiyun  *	Laxman Dewangan <ldewangan@nvidia.com>
9*4882a593Smuzhiyun  *	Chaitanya Bandi <bandik@nvidia.com>
10*4882a593Smuzhiyun  *	Mallikarjun Kasoju <mkasoju@nvidia.com>
11*4882a593Smuzhiyun  */
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun /****************** Teminology used in driver ********************
14*4882a593Smuzhiyun  * Here are some terminology used from datasheet for quick reference:
15*4882a593Smuzhiyun  * Flexible Power Sequence (FPS):
16*4882a593Smuzhiyun  * The Flexible Power Sequencer (FPS) allows each regulator to power up under
17*4882a593Smuzhiyun  * hardware or software control. Additionally, each regulator can power on
18*4882a593Smuzhiyun  * independently or among a group of other regulators with an adjustable
19*4882a593Smuzhiyun  * power-up and power-down delays (sequencing). GPIO1, GPIO2, and GPIO3 can
20*4882a593Smuzhiyun  * be programmed to be part of a sequence allowing external regulators to be
21*4882a593Smuzhiyun  * sequenced along with internal regulators. 32KHz clock can be programmed to
22*4882a593Smuzhiyun  * be part of a sequence.
23*4882a593Smuzhiyun  * There is 3 FPS confguration registers and all resources are configured to
24*4882a593Smuzhiyun  * any of these FPS or no FPS.
25*4882a593Smuzhiyun  */
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #include <linux/i2c.h>
28*4882a593Smuzhiyun #include <linux/interrupt.h>
29*4882a593Smuzhiyun #include <linux/mfd/core.h>
30*4882a593Smuzhiyun #include <linux/mfd/max77620.h>
31*4882a593Smuzhiyun #include <linux/init.h>
32*4882a593Smuzhiyun #include <linux/of.h>
33*4882a593Smuzhiyun #include <linux/of_device.h>
34*4882a593Smuzhiyun #include <linux/regmap.h>
35*4882a593Smuzhiyun #include <linux/slab.h>
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun static struct max77620_chip *max77620_scratch;
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun static const struct resource gpio_resources[] = {
40*4882a593Smuzhiyun 	DEFINE_RES_IRQ(MAX77620_IRQ_TOP_GPIO),
41*4882a593Smuzhiyun };
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun static const struct resource power_resources[] = {
44*4882a593Smuzhiyun 	DEFINE_RES_IRQ(MAX77620_IRQ_LBT_MBATLOW),
45*4882a593Smuzhiyun };
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun static const struct resource rtc_resources[] = {
48*4882a593Smuzhiyun 	DEFINE_RES_IRQ(MAX77620_IRQ_TOP_RTC),
49*4882a593Smuzhiyun };
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun static const struct resource thermal_resources[] = {
52*4882a593Smuzhiyun 	DEFINE_RES_IRQ(MAX77620_IRQ_LBT_TJALRM1),
53*4882a593Smuzhiyun 	DEFINE_RES_IRQ(MAX77620_IRQ_LBT_TJALRM2),
54*4882a593Smuzhiyun };
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun static const struct regmap_irq max77620_top_irqs[] = {
57*4882a593Smuzhiyun 	REGMAP_IRQ_REG(MAX77620_IRQ_TOP_GLBL, 0, MAX77620_IRQ_TOP_GLBL_MASK),
58*4882a593Smuzhiyun 	REGMAP_IRQ_REG(MAX77620_IRQ_TOP_SD, 0, MAX77620_IRQ_TOP_SD_MASK),
59*4882a593Smuzhiyun 	REGMAP_IRQ_REG(MAX77620_IRQ_TOP_LDO, 0, MAX77620_IRQ_TOP_LDO_MASK),
60*4882a593Smuzhiyun 	REGMAP_IRQ_REG(MAX77620_IRQ_TOP_GPIO, 0, MAX77620_IRQ_TOP_GPIO_MASK),
61*4882a593Smuzhiyun 	REGMAP_IRQ_REG(MAX77620_IRQ_TOP_RTC, 0, MAX77620_IRQ_TOP_RTC_MASK),
62*4882a593Smuzhiyun 	REGMAP_IRQ_REG(MAX77620_IRQ_TOP_32K, 0, MAX77620_IRQ_TOP_32K_MASK),
63*4882a593Smuzhiyun 	REGMAP_IRQ_REG(MAX77620_IRQ_TOP_ONOFF, 0, MAX77620_IRQ_TOP_ONOFF_MASK),
64*4882a593Smuzhiyun 	REGMAP_IRQ_REG(MAX77620_IRQ_LBT_MBATLOW, 1, MAX77620_IRQ_LBM_MASK),
65*4882a593Smuzhiyun 	REGMAP_IRQ_REG(MAX77620_IRQ_LBT_TJALRM1, 1, MAX77620_IRQ_TJALRM1_MASK),
66*4882a593Smuzhiyun 	REGMAP_IRQ_REG(MAX77620_IRQ_LBT_TJALRM2, 1, MAX77620_IRQ_TJALRM2_MASK),
67*4882a593Smuzhiyun };
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun static const struct mfd_cell max77620_children[] = {
70*4882a593Smuzhiyun 	{ .name = "max77620-pinctrl", },
71*4882a593Smuzhiyun 	{ .name = "max77620-clock", },
72*4882a593Smuzhiyun 	{ .name = "max77620-pmic", },
73*4882a593Smuzhiyun 	{ .name = "max77620-watchdog", },
74*4882a593Smuzhiyun 	{
75*4882a593Smuzhiyun 		.name = "max77620-gpio",
76*4882a593Smuzhiyun 		.resources = gpio_resources,
77*4882a593Smuzhiyun 		.num_resources = ARRAY_SIZE(gpio_resources),
78*4882a593Smuzhiyun 	}, {
79*4882a593Smuzhiyun 		.name = "max77620-rtc",
80*4882a593Smuzhiyun 		.resources = rtc_resources,
81*4882a593Smuzhiyun 		.num_resources = ARRAY_SIZE(rtc_resources),
82*4882a593Smuzhiyun 	}, {
83*4882a593Smuzhiyun 		.name = "max77620-power",
84*4882a593Smuzhiyun 		.resources = power_resources,
85*4882a593Smuzhiyun 		.num_resources = ARRAY_SIZE(power_resources),
86*4882a593Smuzhiyun 	}, {
87*4882a593Smuzhiyun 		.name = "max77620-thermal",
88*4882a593Smuzhiyun 		.resources = thermal_resources,
89*4882a593Smuzhiyun 		.num_resources = ARRAY_SIZE(thermal_resources),
90*4882a593Smuzhiyun 	},
91*4882a593Smuzhiyun };
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun static const struct mfd_cell max20024_children[] = {
94*4882a593Smuzhiyun 	{ .name = "max20024-pinctrl", },
95*4882a593Smuzhiyun 	{ .name = "max77620-clock", },
96*4882a593Smuzhiyun 	{ .name = "max20024-pmic", },
97*4882a593Smuzhiyun 	{ .name = "max77620-watchdog", },
98*4882a593Smuzhiyun 	{
99*4882a593Smuzhiyun 		.name = "max77620-gpio",
100*4882a593Smuzhiyun 		.resources = gpio_resources,
101*4882a593Smuzhiyun 		.num_resources = ARRAY_SIZE(gpio_resources),
102*4882a593Smuzhiyun 	}, {
103*4882a593Smuzhiyun 		.name = "max77620-rtc",
104*4882a593Smuzhiyun 		.resources = rtc_resources,
105*4882a593Smuzhiyun 		.num_resources = ARRAY_SIZE(rtc_resources),
106*4882a593Smuzhiyun 	}, {
107*4882a593Smuzhiyun 		.name = "max20024-power",
108*4882a593Smuzhiyun 		.resources = power_resources,
109*4882a593Smuzhiyun 		.num_resources = ARRAY_SIZE(power_resources),
110*4882a593Smuzhiyun 	},
111*4882a593Smuzhiyun };
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun static const struct mfd_cell max77663_children[] = {
114*4882a593Smuzhiyun 	{ .name = "max77620-pinctrl", },
115*4882a593Smuzhiyun 	{ .name = "max77620-clock", },
116*4882a593Smuzhiyun 	{ .name = "max77663-pmic", },
117*4882a593Smuzhiyun 	{ .name = "max77620-watchdog", },
118*4882a593Smuzhiyun 	{
119*4882a593Smuzhiyun 		.name = "max77620-gpio",
120*4882a593Smuzhiyun 		.resources = gpio_resources,
121*4882a593Smuzhiyun 		.num_resources = ARRAY_SIZE(gpio_resources),
122*4882a593Smuzhiyun 	}, {
123*4882a593Smuzhiyun 		.name = "max77620-rtc",
124*4882a593Smuzhiyun 		.resources = rtc_resources,
125*4882a593Smuzhiyun 		.num_resources = ARRAY_SIZE(rtc_resources),
126*4882a593Smuzhiyun 	}, {
127*4882a593Smuzhiyun 		.name = "max77663-power",
128*4882a593Smuzhiyun 		.resources = power_resources,
129*4882a593Smuzhiyun 		.num_resources = ARRAY_SIZE(power_resources),
130*4882a593Smuzhiyun 	},
131*4882a593Smuzhiyun };
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun static const struct regmap_range max77620_readable_ranges[] = {
134*4882a593Smuzhiyun 	regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4),
135*4882a593Smuzhiyun };
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun static const struct regmap_access_table max77620_readable_table = {
138*4882a593Smuzhiyun 	.yes_ranges = max77620_readable_ranges,
139*4882a593Smuzhiyun 	.n_yes_ranges = ARRAY_SIZE(max77620_readable_ranges),
140*4882a593Smuzhiyun };
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun static const struct regmap_range max20024_readable_ranges[] = {
143*4882a593Smuzhiyun 	regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4),
144*4882a593Smuzhiyun 	regmap_reg_range(MAX20024_REG_MAX_ADD, MAX20024_REG_MAX_ADD),
145*4882a593Smuzhiyun };
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun static const struct regmap_access_table max20024_readable_table = {
148*4882a593Smuzhiyun 	.yes_ranges = max20024_readable_ranges,
149*4882a593Smuzhiyun 	.n_yes_ranges = ARRAY_SIZE(max20024_readable_ranges),
150*4882a593Smuzhiyun };
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun static const struct regmap_range max77620_writable_ranges[] = {
153*4882a593Smuzhiyun 	regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4),
154*4882a593Smuzhiyun };
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun static const struct regmap_access_table max77620_writable_table = {
157*4882a593Smuzhiyun 	.yes_ranges = max77620_writable_ranges,
158*4882a593Smuzhiyun 	.n_yes_ranges = ARRAY_SIZE(max77620_writable_ranges),
159*4882a593Smuzhiyun };
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun static const struct regmap_range max77620_cacheable_ranges[] = {
162*4882a593Smuzhiyun 	regmap_reg_range(MAX77620_REG_SD0_CFG, MAX77620_REG_LDO_CFG3),
163*4882a593Smuzhiyun 	regmap_reg_range(MAX77620_REG_FPS_CFG0, MAX77620_REG_FPS_SD3),
164*4882a593Smuzhiyun };
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun static const struct regmap_access_table max77620_volatile_table = {
167*4882a593Smuzhiyun 	.no_ranges = max77620_cacheable_ranges,
168*4882a593Smuzhiyun 	.n_no_ranges = ARRAY_SIZE(max77620_cacheable_ranges),
169*4882a593Smuzhiyun };
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun static const struct regmap_config max77620_regmap_config = {
172*4882a593Smuzhiyun 	.name = "power-slave",
173*4882a593Smuzhiyun 	.reg_bits = 8,
174*4882a593Smuzhiyun 	.val_bits = 8,
175*4882a593Smuzhiyun 	.max_register = MAX77620_REG_DVSSD4 + 1,
176*4882a593Smuzhiyun 	.cache_type = REGCACHE_RBTREE,
177*4882a593Smuzhiyun 	.rd_table = &max77620_readable_table,
178*4882a593Smuzhiyun 	.wr_table = &max77620_writable_table,
179*4882a593Smuzhiyun 	.volatile_table = &max77620_volatile_table,
180*4882a593Smuzhiyun 	.use_single_write = true,
181*4882a593Smuzhiyun };
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun static const struct regmap_config max20024_regmap_config = {
184*4882a593Smuzhiyun 	.name = "power-slave",
185*4882a593Smuzhiyun 	.reg_bits = 8,
186*4882a593Smuzhiyun 	.val_bits = 8,
187*4882a593Smuzhiyun 	.max_register = MAX20024_REG_MAX_ADD + 1,
188*4882a593Smuzhiyun 	.cache_type = REGCACHE_RBTREE,
189*4882a593Smuzhiyun 	.rd_table = &max20024_readable_table,
190*4882a593Smuzhiyun 	.wr_table = &max77620_writable_table,
191*4882a593Smuzhiyun 	.volatile_table = &max77620_volatile_table,
192*4882a593Smuzhiyun };
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun static const struct regmap_range max77663_readable_ranges[] = {
195*4882a593Smuzhiyun 	regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_CID5),
196*4882a593Smuzhiyun };
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun static const struct regmap_access_table max77663_readable_table = {
199*4882a593Smuzhiyun 	.yes_ranges = max77663_readable_ranges,
200*4882a593Smuzhiyun 	.n_yes_ranges = ARRAY_SIZE(max77663_readable_ranges),
201*4882a593Smuzhiyun };
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun static const struct regmap_range max77663_writable_ranges[] = {
204*4882a593Smuzhiyun 	regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_CID5),
205*4882a593Smuzhiyun };
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun static const struct regmap_access_table max77663_writable_table = {
208*4882a593Smuzhiyun 	.yes_ranges = max77663_writable_ranges,
209*4882a593Smuzhiyun 	.n_yes_ranges = ARRAY_SIZE(max77663_writable_ranges),
210*4882a593Smuzhiyun };
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun static const struct regmap_config max77663_regmap_config = {
213*4882a593Smuzhiyun 	.name = "power-slave",
214*4882a593Smuzhiyun 	.reg_bits = 8,
215*4882a593Smuzhiyun 	.val_bits = 8,
216*4882a593Smuzhiyun 	.max_register = MAX77620_REG_CID5 + 1,
217*4882a593Smuzhiyun 	.cache_type = REGCACHE_RBTREE,
218*4882a593Smuzhiyun 	.rd_table = &max77663_readable_table,
219*4882a593Smuzhiyun 	.wr_table = &max77663_writable_table,
220*4882a593Smuzhiyun 	.volatile_table = &max77620_volatile_table,
221*4882a593Smuzhiyun };
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun /*
224*4882a593Smuzhiyun  * MAX77620 and MAX20024 has the following steps of the interrupt handling
225*4882a593Smuzhiyun  * for TOP interrupts:
226*4882a593Smuzhiyun  * 1. When interrupt occurs from PMIC, mask the PMIC interrupt by setting GLBLM.
227*4882a593Smuzhiyun  * 2. Read IRQTOP and service the interrupt.
228*4882a593Smuzhiyun  * 3. Once all interrupts has been checked and serviced, the interrupt service
229*4882a593Smuzhiyun  *    routine un-masks the hardware interrupt line by clearing GLBLM.
230*4882a593Smuzhiyun  */
max77620_irq_global_mask(void * irq_drv_data)231*4882a593Smuzhiyun static int max77620_irq_global_mask(void *irq_drv_data)
232*4882a593Smuzhiyun {
233*4882a593Smuzhiyun 	struct max77620_chip *chip = irq_drv_data;
234*4882a593Smuzhiyun 	int ret;
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun 	ret = regmap_update_bits(chip->rmap, MAX77620_REG_INTENLBT,
237*4882a593Smuzhiyun 				 MAX77620_GLBLM_MASK, MAX77620_GLBLM_MASK);
238*4882a593Smuzhiyun 	if (ret < 0)
239*4882a593Smuzhiyun 		dev_err(chip->dev, "Failed to set GLBLM: %d\n", ret);
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 	return ret;
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun 
max77620_irq_global_unmask(void * irq_drv_data)244*4882a593Smuzhiyun static int max77620_irq_global_unmask(void *irq_drv_data)
245*4882a593Smuzhiyun {
246*4882a593Smuzhiyun 	struct max77620_chip *chip = irq_drv_data;
247*4882a593Smuzhiyun 	int ret;
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun 	ret = regmap_update_bits(chip->rmap, MAX77620_REG_INTENLBT,
250*4882a593Smuzhiyun 				 MAX77620_GLBLM_MASK, 0);
251*4882a593Smuzhiyun 	if (ret < 0)
252*4882a593Smuzhiyun 		dev_err(chip->dev, "Failed to reset GLBLM: %d\n", ret);
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	return ret;
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun static struct regmap_irq_chip max77620_top_irq_chip = {
258*4882a593Smuzhiyun 	.name = "max77620-top",
259*4882a593Smuzhiyun 	.irqs = max77620_top_irqs,
260*4882a593Smuzhiyun 	.num_irqs = ARRAY_SIZE(max77620_top_irqs),
261*4882a593Smuzhiyun 	.num_regs = 2,
262*4882a593Smuzhiyun 	.status_base = MAX77620_REG_IRQTOP,
263*4882a593Smuzhiyun 	.mask_base = MAX77620_REG_IRQTOPM,
264*4882a593Smuzhiyun 	.handle_pre_irq = max77620_irq_global_mask,
265*4882a593Smuzhiyun 	.handle_post_irq = max77620_irq_global_unmask,
266*4882a593Smuzhiyun };
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun /* max77620_get_fps_period_reg_value:  Get FPS bit field value from
269*4882a593Smuzhiyun  *				       requested periods.
270*4882a593Smuzhiyun  * MAX77620 supports the FPS period of 40, 80, 160, 320, 540, 1280, 2560
271*4882a593Smuzhiyun  * and 5120 microseconds. MAX20024 supports the FPS period of 20, 40, 80,
272*4882a593Smuzhiyun  * 160, 320, 540, 1280 and 2560 microseconds.
273*4882a593Smuzhiyun  * The FPS register has 3 bits field to set the FPS period as
274*4882a593Smuzhiyun  * bits		max77620		max20024
275*4882a593Smuzhiyun  * 000		40			20
276*4882a593Smuzhiyun  * 001		80			40
277*4882a593Smuzhiyun  * :::
278*4882a593Smuzhiyun */
max77620_get_fps_period_reg_value(struct max77620_chip * chip,int tperiod)279*4882a593Smuzhiyun static int max77620_get_fps_period_reg_value(struct max77620_chip *chip,
280*4882a593Smuzhiyun 					     int tperiod)
281*4882a593Smuzhiyun {
282*4882a593Smuzhiyun 	int fps_min_period;
283*4882a593Smuzhiyun 	int i;
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun 	switch (chip->chip_id) {
286*4882a593Smuzhiyun 	case MAX20024:
287*4882a593Smuzhiyun 		fps_min_period = MAX20024_FPS_PERIOD_MIN_US;
288*4882a593Smuzhiyun 		break;
289*4882a593Smuzhiyun 	case MAX77620:
290*4882a593Smuzhiyun 		fps_min_period = MAX77620_FPS_PERIOD_MIN_US;
291*4882a593Smuzhiyun 		break;
292*4882a593Smuzhiyun 	case MAX77663:
293*4882a593Smuzhiyun 		fps_min_period = MAX20024_FPS_PERIOD_MIN_US;
294*4882a593Smuzhiyun 		break;
295*4882a593Smuzhiyun 	default:
296*4882a593Smuzhiyun 		return -EINVAL;
297*4882a593Smuzhiyun 	}
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 	for (i = 0; i < 7; i++) {
300*4882a593Smuzhiyun 		if (fps_min_period >= tperiod)
301*4882a593Smuzhiyun 			return i;
302*4882a593Smuzhiyun 		fps_min_period *= 2;
303*4882a593Smuzhiyun 	}
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun 	return i;
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun /* max77620_config_fps: Configure FPS configuration registers
309*4882a593Smuzhiyun  *			based on platform specific information.
310*4882a593Smuzhiyun  */
max77620_config_fps(struct max77620_chip * chip,struct device_node * fps_np)311*4882a593Smuzhiyun static int max77620_config_fps(struct max77620_chip *chip,
312*4882a593Smuzhiyun 			       struct device_node *fps_np)
313*4882a593Smuzhiyun {
314*4882a593Smuzhiyun 	struct device *dev = chip->dev;
315*4882a593Smuzhiyun 	unsigned int mask = 0, config = 0;
316*4882a593Smuzhiyun 	u32 fps_max_period;
317*4882a593Smuzhiyun 	u32 param_val;
318*4882a593Smuzhiyun 	int tperiod, fps_id;
319*4882a593Smuzhiyun 	int ret;
320*4882a593Smuzhiyun 	char fps_name[10];
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 	switch (chip->chip_id) {
323*4882a593Smuzhiyun 	case MAX20024:
324*4882a593Smuzhiyun 		fps_max_period = MAX20024_FPS_PERIOD_MAX_US;
325*4882a593Smuzhiyun 		break;
326*4882a593Smuzhiyun 	case MAX77620:
327*4882a593Smuzhiyun 		fps_max_period = MAX77620_FPS_PERIOD_MAX_US;
328*4882a593Smuzhiyun 		break;
329*4882a593Smuzhiyun 	case MAX77663:
330*4882a593Smuzhiyun 		fps_max_period = MAX20024_FPS_PERIOD_MAX_US;
331*4882a593Smuzhiyun 		break;
332*4882a593Smuzhiyun 	default:
333*4882a593Smuzhiyun 		return -EINVAL;
334*4882a593Smuzhiyun 	}
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 	for (fps_id = 0; fps_id < MAX77620_FPS_COUNT; fps_id++) {
337*4882a593Smuzhiyun 		sprintf(fps_name, "fps%d", fps_id);
338*4882a593Smuzhiyun 		if (of_node_name_eq(fps_np, fps_name))
339*4882a593Smuzhiyun 			break;
340*4882a593Smuzhiyun 	}
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 	if (fps_id == MAX77620_FPS_COUNT) {
343*4882a593Smuzhiyun 		dev_err(dev, "FPS node name %pOFn is not valid\n", fps_np);
344*4882a593Smuzhiyun 		return -EINVAL;
345*4882a593Smuzhiyun 	}
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 	ret = of_property_read_u32(fps_np, "maxim,shutdown-fps-time-period-us",
348*4882a593Smuzhiyun 				   &param_val);
349*4882a593Smuzhiyun 	if (!ret) {
350*4882a593Smuzhiyun 		mask |= MAX77620_FPS_TIME_PERIOD_MASK;
351*4882a593Smuzhiyun 		chip->shutdown_fps_period[fps_id] = min(param_val,
352*4882a593Smuzhiyun 							fps_max_period);
353*4882a593Smuzhiyun 		tperiod = max77620_get_fps_period_reg_value(chip,
354*4882a593Smuzhiyun 				chip->shutdown_fps_period[fps_id]);
355*4882a593Smuzhiyun 		config |= tperiod << MAX77620_FPS_TIME_PERIOD_SHIFT;
356*4882a593Smuzhiyun 	}
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun 	ret = of_property_read_u32(fps_np, "maxim,suspend-fps-time-period-us",
359*4882a593Smuzhiyun 				   &param_val);
360*4882a593Smuzhiyun 	if (!ret)
361*4882a593Smuzhiyun 		chip->suspend_fps_period[fps_id] = min(param_val,
362*4882a593Smuzhiyun 						       fps_max_period);
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	ret = of_property_read_u32(fps_np, "maxim,fps-event-source",
365*4882a593Smuzhiyun 				   &param_val);
366*4882a593Smuzhiyun 	if (!ret) {
367*4882a593Smuzhiyun 		if (param_val > 2) {
368*4882a593Smuzhiyun 			dev_err(dev, "FPS%d event-source invalid\n", fps_id);
369*4882a593Smuzhiyun 			return -EINVAL;
370*4882a593Smuzhiyun 		}
371*4882a593Smuzhiyun 		mask |= MAX77620_FPS_EN_SRC_MASK;
372*4882a593Smuzhiyun 		config |= param_val << MAX77620_FPS_EN_SRC_SHIFT;
373*4882a593Smuzhiyun 		if (param_val == 2) {
374*4882a593Smuzhiyun 			mask |= MAX77620_FPS_ENFPS_SW_MASK;
375*4882a593Smuzhiyun 			config |= MAX77620_FPS_ENFPS_SW;
376*4882a593Smuzhiyun 		}
377*4882a593Smuzhiyun 	}
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun 	if (!chip->sleep_enable && !chip->enable_global_lpm) {
380*4882a593Smuzhiyun 		ret = of_property_read_u32(fps_np,
381*4882a593Smuzhiyun 				"maxim,device-state-on-disabled-event",
382*4882a593Smuzhiyun 				&param_val);
383*4882a593Smuzhiyun 		if (!ret) {
384*4882a593Smuzhiyun 			if (param_val == 0)
385*4882a593Smuzhiyun 				chip->sleep_enable = true;
386*4882a593Smuzhiyun 			else if (param_val == 1)
387*4882a593Smuzhiyun 				chip->enable_global_lpm = true;
388*4882a593Smuzhiyun 		}
389*4882a593Smuzhiyun 	}
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 	ret = regmap_update_bits(chip->rmap, MAX77620_REG_FPS_CFG0 + fps_id,
392*4882a593Smuzhiyun 				 mask, config);
393*4882a593Smuzhiyun 	if (ret < 0) {
394*4882a593Smuzhiyun 		dev_err(dev, "Failed to update FPS CFG: %d\n", ret);
395*4882a593Smuzhiyun 		return ret;
396*4882a593Smuzhiyun 	}
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun 	return 0;
399*4882a593Smuzhiyun }
400*4882a593Smuzhiyun 
max77620_initialise_fps(struct max77620_chip * chip)401*4882a593Smuzhiyun static int max77620_initialise_fps(struct max77620_chip *chip)
402*4882a593Smuzhiyun {
403*4882a593Smuzhiyun 	struct device *dev = chip->dev;
404*4882a593Smuzhiyun 	struct device_node *fps_np, *fps_child;
405*4882a593Smuzhiyun 	u8 config;
406*4882a593Smuzhiyun 	int fps_id;
407*4882a593Smuzhiyun 	int ret;
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun 	for (fps_id = 0; fps_id < MAX77620_FPS_COUNT; fps_id++) {
410*4882a593Smuzhiyun 		chip->shutdown_fps_period[fps_id] = -1;
411*4882a593Smuzhiyun 		chip->suspend_fps_period[fps_id] = -1;
412*4882a593Smuzhiyun 	}
413*4882a593Smuzhiyun 
414*4882a593Smuzhiyun 	fps_np = of_get_child_by_name(dev->of_node, "fps");
415*4882a593Smuzhiyun 	if (!fps_np)
416*4882a593Smuzhiyun 		goto skip_fps;
417*4882a593Smuzhiyun 
418*4882a593Smuzhiyun 	for_each_child_of_node(fps_np, fps_child) {
419*4882a593Smuzhiyun 		ret = max77620_config_fps(chip, fps_child);
420*4882a593Smuzhiyun 		if (ret < 0) {
421*4882a593Smuzhiyun 			of_node_put(fps_child);
422*4882a593Smuzhiyun 			of_node_put(fps_np);
423*4882a593Smuzhiyun 			return ret;
424*4882a593Smuzhiyun 		}
425*4882a593Smuzhiyun 	}
426*4882a593Smuzhiyun 	of_node_put(fps_np);
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun 	config = chip->enable_global_lpm ? MAX77620_ONOFFCNFG2_SLP_LPM_MSK : 0;
429*4882a593Smuzhiyun 	ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
430*4882a593Smuzhiyun 				 MAX77620_ONOFFCNFG2_SLP_LPM_MSK, config);
431*4882a593Smuzhiyun 	if (ret < 0) {
432*4882a593Smuzhiyun 		dev_err(dev, "Failed to update SLP_LPM: %d\n", ret);
433*4882a593Smuzhiyun 		return ret;
434*4882a593Smuzhiyun 	}
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun skip_fps:
437*4882a593Smuzhiyun 	if (chip->chip_id == MAX77663)
438*4882a593Smuzhiyun 		return 0;
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun 	/* Enable wake on EN0 pin */
441*4882a593Smuzhiyun 	ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
442*4882a593Smuzhiyun 				 MAX77620_ONOFFCNFG2_WK_EN0,
443*4882a593Smuzhiyun 				 MAX77620_ONOFFCNFG2_WK_EN0);
444*4882a593Smuzhiyun 	if (ret < 0) {
445*4882a593Smuzhiyun 		dev_err(dev, "Failed to update WK_EN0: %d\n", ret);
446*4882a593Smuzhiyun 		return ret;
447*4882a593Smuzhiyun 	}
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun 	/* For MAX20024, SLPEN will be POR reset if CLRSE is b11 */
450*4882a593Smuzhiyun 	if ((chip->chip_id == MAX20024) && chip->sleep_enable) {
451*4882a593Smuzhiyun 		config = MAX77620_ONOFFCNFG1_SLPEN | MAX20024_ONOFFCNFG1_CLRSE;
452*4882a593Smuzhiyun 		ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG1,
453*4882a593Smuzhiyun 					 config, config);
454*4882a593Smuzhiyun 		if (ret < 0) {
455*4882a593Smuzhiyun 			dev_err(dev, "Failed to update SLPEN: %d\n", ret);
456*4882a593Smuzhiyun 			return ret;
457*4882a593Smuzhiyun 		}
458*4882a593Smuzhiyun 	}
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun 	return 0;
461*4882a593Smuzhiyun }
462*4882a593Smuzhiyun 
max77620_read_es_version(struct max77620_chip * chip)463*4882a593Smuzhiyun static int max77620_read_es_version(struct max77620_chip *chip)
464*4882a593Smuzhiyun {
465*4882a593Smuzhiyun 	unsigned int val;
466*4882a593Smuzhiyun 	u8 cid_val[6];
467*4882a593Smuzhiyun 	int i;
468*4882a593Smuzhiyun 	int ret;
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun 	for (i = MAX77620_REG_CID0; i <= MAX77620_REG_CID5; i++) {
471*4882a593Smuzhiyun 		ret = regmap_read(chip->rmap, i, &val);
472*4882a593Smuzhiyun 		if (ret < 0) {
473*4882a593Smuzhiyun 			dev_err(chip->dev, "Failed to read CID: %d\n", ret);
474*4882a593Smuzhiyun 			return ret;
475*4882a593Smuzhiyun 		}
476*4882a593Smuzhiyun 		dev_dbg(chip->dev, "CID%d: 0x%02x\n",
477*4882a593Smuzhiyun 			i - MAX77620_REG_CID0, val);
478*4882a593Smuzhiyun 		cid_val[i - MAX77620_REG_CID0] = val;
479*4882a593Smuzhiyun 	}
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun 	/* CID4 is OTP Version  and CID5 is ES version */
482*4882a593Smuzhiyun 	dev_info(chip->dev, "PMIC Version OTP:0x%02X and ES:0x%X\n",
483*4882a593Smuzhiyun 		 cid_val[4], MAX77620_CID5_DIDM(cid_val[5]));
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun 	return ret;
486*4882a593Smuzhiyun }
487*4882a593Smuzhiyun 
max77620_pm_power_off(void)488*4882a593Smuzhiyun static void max77620_pm_power_off(void)
489*4882a593Smuzhiyun {
490*4882a593Smuzhiyun 	struct max77620_chip *chip = max77620_scratch;
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 	regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG1,
493*4882a593Smuzhiyun 			   MAX77620_ONOFFCNFG1_SFT_RST,
494*4882a593Smuzhiyun 			   MAX77620_ONOFFCNFG1_SFT_RST);
495*4882a593Smuzhiyun }
496*4882a593Smuzhiyun 
max77620_probe(struct i2c_client * client,const struct i2c_device_id * id)497*4882a593Smuzhiyun static int max77620_probe(struct i2c_client *client,
498*4882a593Smuzhiyun 			  const struct i2c_device_id *id)
499*4882a593Smuzhiyun {
500*4882a593Smuzhiyun 	const struct regmap_config *rmap_config;
501*4882a593Smuzhiyun 	struct max77620_chip *chip;
502*4882a593Smuzhiyun 	const struct mfd_cell *mfd_cells;
503*4882a593Smuzhiyun 	int n_mfd_cells;
504*4882a593Smuzhiyun 	bool pm_off;
505*4882a593Smuzhiyun 	int ret;
506*4882a593Smuzhiyun 
507*4882a593Smuzhiyun 	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
508*4882a593Smuzhiyun 	if (!chip)
509*4882a593Smuzhiyun 		return -ENOMEM;
510*4882a593Smuzhiyun 
511*4882a593Smuzhiyun 	i2c_set_clientdata(client, chip);
512*4882a593Smuzhiyun 	chip->dev = &client->dev;
513*4882a593Smuzhiyun 	chip->chip_irq = client->irq;
514*4882a593Smuzhiyun 	chip->chip_id = (enum max77620_chip_id)id->driver_data;
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun 	switch (chip->chip_id) {
517*4882a593Smuzhiyun 	case MAX77620:
518*4882a593Smuzhiyun 		mfd_cells = max77620_children;
519*4882a593Smuzhiyun 		n_mfd_cells = ARRAY_SIZE(max77620_children);
520*4882a593Smuzhiyun 		rmap_config = &max77620_regmap_config;
521*4882a593Smuzhiyun 		break;
522*4882a593Smuzhiyun 	case MAX20024:
523*4882a593Smuzhiyun 		mfd_cells = max20024_children;
524*4882a593Smuzhiyun 		n_mfd_cells = ARRAY_SIZE(max20024_children);
525*4882a593Smuzhiyun 		rmap_config = &max20024_regmap_config;
526*4882a593Smuzhiyun 		break;
527*4882a593Smuzhiyun 	case MAX77663:
528*4882a593Smuzhiyun 		mfd_cells = max77663_children;
529*4882a593Smuzhiyun 		n_mfd_cells = ARRAY_SIZE(max77663_children);
530*4882a593Smuzhiyun 		rmap_config = &max77663_regmap_config;
531*4882a593Smuzhiyun 		break;
532*4882a593Smuzhiyun 	default:
533*4882a593Smuzhiyun 		dev_err(chip->dev, "ChipID is invalid %d\n", chip->chip_id);
534*4882a593Smuzhiyun 		return -EINVAL;
535*4882a593Smuzhiyun 	}
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun 	chip->rmap = devm_regmap_init_i2c(client, rmap_config);
538*4882a593Smuzhiyun 	if (IS_ERR(chip->rmap)) {
539*4882a593Smuzhiyun 		ret = PTR_ERR(chip->rmap);
540*4882a593Smuzhiyun 		dev_err(chip->dev, "Failed to initialise regmap: %d\n", ret);
541*4882a593Smuzhiyun 		return ret;
542*4882a593Smuzhiyun 	}
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun 	ret = max77620_read_es_version(chip);
545*4882a593Smuzhiyun 	if (ret < 0)
546*4882a593Smuzhiyun 		return ret;
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun 	max77620_top_irq_chip.irq_drv_data = chip;
549*4882a593Smuzhiyun 	ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq,
550*4882a593Smuzhiyun 				       IRQF_ONESHOT | IRQF_SHARED, 0,
551*4882a593Smuzhiyun 				       &max77620_top_irq_chip,
552*4882a593Smuzhiyun 				       &chip->top_irq_data);
553*4882a593Smuzhiyun 	if (ret < 0) {
554*4882a593Smuzhiyun 		dev_err(chip->dev, "Failed to add regmap irq: %d\n", ret);
555*4882a593Smuzhiyun 		return ret;
556*4882a593Smuzhiyun 	}
557*4882a593Smuzhiyun 
558*4882a593Smuzhiyun 	ret = max77620_initialise_fps(chip);
559*4882a593Smuzhiyun 	if (ret < 0)
560*4882a593Smuzhiyun 		return ret;
561*4882a593Smuzhiyun 
562*4882a593Smuzhiyun 	ret =  devm_mfd_add_devices(chip->dev, PLATFORM_DEVID_NONE,
563*4882a593Smuzhiyun 				    mfd_cells, n_mfd_cells, NULL, 0,
564*4882a593Smuzhiyun 				    regmap_irq_get_domain(chip->top_irq_data));
565*4882a593Smuzhiyun 	if (ret < 0) {
566*4882a593Smuzhiyun 		dev_err(chip->dev, "Failed to add MFD children: %d\n", ret);
567*4882a593Smuzhiyun 		return ret;
568*4882a593Smuzhiyun 	}
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun 	pm_off = of_device_is_system_power_controller(client->dev.of_node);
571*4882a593Smuzhiyun 	if (pm_off && !pm_power_off) {
572*4882a593Smuzhiyun 		max77620_scratch = chip;
573*4882a593Smuzhiyun 		pm_power_off = max77620_pm_power_off;
574*4882a593Smuzhiyun 	}
575*4882a593Smuzhiyun 
576*4882a593Smuzhiyun 	return 0;
577*4882a593Smuzhiyun }
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
max77620_set_fps_period(struct max77620_chip * chip,int fps_id,int time_period)580*4882a593Smuzhiyun static int max77620_set_fps_period(struct max77620_chip *chip,
581*4882a593Smuzhiyun 				   int fps_id, int time_period)
582*4882a593Smuzhiyun {
583*4882a593Smuzhiyun 	int period = max77620_get_fps_period_reg_value(chip, time_period);
584*4882a593Smuzhiyun 	int ret;
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun 	ret = regmap_update_bits(chip->rmap, MAX77620_REG_FPS_CFG0 + fps_id,
587*4882a593Smuzhiyun 				 MAX77620_FPS_TIME_PERIOD_MASK,
588*4882a593Smuzhiyun 				 period << MAX77620_FPS_TIME_PERIOD_SHIFT);
589*4882a593Smuzhiyun 	if (ret < 0) {
590*4882a593Smuzhiyun 		dev_err(chip->dev, "Failed to update FPS period: %d\n", ret);
591*4882a593Smuzhiyun 		return ret;
592*4882a593Smuzhiyun 	}
593*4882a593Smuzhiyun 
594*4882a593Smuzhiyun 	return 0;
595*4882a593Smuzhiyun }
596*4882a593Smuzhiyun 
max77620_i2c_suspend(struct device * dev)597*4882a593Smuzhiyun static int max77620_i2c_suspend(struct device *dev)
598*4882a593Smuzhiyun {
599*4882a593Smuzhiyun 	struct max77620_chip *chip = dev_get_drvdata(dev);
600*4882a593Smuzhiyun 	struct i2c_client *client = to_i2c_client(dev);
601*4882a593Smuzhiyun 	unsigned int config;
602*4882a593Smuzhiyun 	int fps;
603*4882a593Smuzhiyun 	int ret;
604*4882a593Smuzhiyun 
605*4882a593Smuzhiyun 	for (fps = 0; fps < MAX77620_FPS_COUNT; fps++) {
606*4882a593Smuzhiyun 		if (chip->suspend_fps_period[fps] < 0)
607*4882a593Smuzhiyun 			continue;
608*4882a593Smuzhiyun 
609*4882a593Smuzhiyun 		ret = max77620_set_fps_period(chip, fps,
610*4882a593Smuzhiyun 					      chip->suspend_fps_period[fps]);
611*4882a593Smuzhiyun 		if (ret < 0)
612*4882a593Smuzhiyun 			return ret;
613*4882a593Smuzhiyun 	}
614*4882a593Smuzhiyun 
615*4882a593Smuzhiyun 	/*
616*4882a593Smuzhiyun 	 * For MAX20024: No need to configure SLPEN on suspend as
617*4882a593Smuzhiyun 	 * it will be configured on Init.
618*4882a593Smuzhiyun 	 */
619*4882a593Smuzhiyun 	if (chip->chip_id == MAX20024)
620*4882a593Smuzhiyun 		goto out;
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun 	config = (chip->sleep_enable) ? MAX77620_ONOFFCNFG1_SLPEN : 0;
623*4882a593Smuzhiyun 	ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG1,
624*4882a593Smuzhiyun 				 MAX77620_ONOFFCNFG1_SLPEN,
625*4882a593Smuzhiyun 				 config);
626*4882a593Smuzhiyun 	if (ret < 0) {
627*4882a593Smuzhiyun 		dev_err(dev, "Failed to configure sleep in suspend: %d\n", ret);
628*4882a593Smuzhiyun 		return ret;
629*4882a593Smuzhiyun 	}
630*4882a593Smuzhiyun 
631*4882a593Smuzhiyun 	if (chip->chip_id == MAX77663)
632*4882a593Smuzhiyun 		goto out;
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun 	/* Disable WK_EN0 */
635*4882a593Smuzhiyun 	ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
636*4882a593Smuzhiyun 				 MAX77620_ONOFFCNFG2_WK_EN0, 0);
637*4882a593Smuzhiyun 	if (ret < 0) {
638*4882a593Smuzhiyun 		dev_err(dev, "Failed to configure WK_EN in suspend: %d\n", ret);
639*4882a593Smuzhiyun 		return ret;
640*4882a593Smuzhiyun 	}
641*4882a593Smuzhiyun 
642*4882a593Smuzhiyun out:
643*4882a593Smuzhiyun 	disable_irq(client->irq);
644*4882a593Smuzhiyun 
645*4882a593Smuzhiyun 	return 0;
646*4882a593Smuzhiyun }
647*4882a593Smuzhiyun 
max77620_i2c_resume(struct device * dev)648*4882a593Smuzhiyun static int max77620_i2c_resume(struct device *dev)
649*4882a593Smuzhiyun {
650*4882a593Smuzhiyun 	struct max77620_chip *chip = dev_get_drvdata(dev);
651*4882a593Smuzhiyun 	struct i2c_client *client = to_i2c_client(dev);
652*4882a593Smuzhiyun 	int ret;
653*4882a593Smuzhiyun 	int fps;
654*4882a593Smuzhiyun 
655*4882a593Smuzhiyun 	for (fps = 0; fps < MAX77620_FPS_COUNT; fps++) {
656*4882a593Smuzhiyun 		if (chip->shutdown_fps_period[fps] < 0)
657*4882a593Smuzhiyun 			continue;
658*4882a593Smuzhiyun 
659*4882a593Smuzhiyun 		ret = max77620_set_fps_period(chip, fps,
660*4882a593Smuzhiyun 					      chip->shutdown_fps_period[fps]);
661*4882a593Smuzhiyun 		if (ret < 0)
662*4882a593Smuzhiyun 			return ret;
663*4882a593Smuzhiyun 	}
664*4882a593Smuzhiyun 
665*4882a593Smuzhiyun 	/*
666*4882a593Smuzhiyun 	 * For MAX20024: No need to configure WKEN0 on resume as
667*4882a593Smuzhiyun 	 * it is configured on Init.
668*4882a593Smuzhiyun 	 */
669*4882a593Smuzhiyun 	if (chip->chip_id == MAX20024 || chip->chip_id == MAX77663)
670*4882a593Smuzhiyun 		goto out;
671*4882a593Smuzhiyun 
672*4882a593Smuzhiyun 	/* Enable WK_EN0 */
673*4882a593Smuzhiyun 	ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
674*4882a593Smuzhiyun 				 MAX77620_ONOFFCNFG2_WK_EN0,
675*4882a593Smuzhiyun 				 MAX77620_ONOFFCNFG2_WK_EN0);
676*4882a593Smuzhiyun 	if (ret < 0) {
677*4882a593Smuzhiyun 		dev_err(dev, "Failed to configure WK_EN0 n resume: %d\n", ret);
678*4882a593Smuzhiyun 		return ret;
679*4882a593Smuzhiyun 	}
680*4882a593Smuzhiyun 
681*4882a593Smuzhiyun out:
682*4882a593Smuzhiyun 	enable_irq(client->irq);
683*4882a593Smuzhiyun 
684*4882a593Smuzhiyun 	return 0;
685*4882a593Smuzhiyun }
686*4882a593Smuzhiyun #endif
687*4882a593Smuzhiyun 
688*4882a593Smuzhiyun static const struct i2c_device_id max77620_id[] = {
689*4882a593Smuzhiyun 	{"max77620", MAX77620},
690*4882a593Smuzhiyun 	{"max20024", MAX20024},
691*4882a593Smuzhiyun 	{"max77663", MAX77663},
692*4882a593Smuzhiyun 	{},
693*4882a593Smuzhiyun };
694*4882a593Smuzhiyun 
695*4882a593Smuzhiyun static const struct dev_pm_ops max77620_pm_ops = {
696*4882a593Smuzhiyun 	SET_SYSTEM_SLEEP_PM_OPS(max77620_i2c_suspend, max77620_i2c_resume)
697*4882a593Smuzhiyun };
698*4882a593Smuzhiyun 
699*4882a593Smuzhiyun static struct i2c_driver max77620_driver = {
700*4882a593Smuzhiyun 	.driver = {
701*4882a593Smuzhiyun 		.name = "max77620",
702*4882a593Smuzhiyun 		.pm = &max77620_pm_ops,
703*4882a593Smuzhiyun 	},
704*4882a593Smuzhiyun 	.probe = max77620_probe,
705*4882a593Smuzhiyun 	.id_table = max77620_id,
706*4882a593Smuzhiyun };
707*4882a593Smuzhiyun builtin_i2c_driver(max77620_driver);
708