xref: /OK3568_Linux_fs/kernel/drivers/mfd/sec-core.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun //
3*4882a593Smuzhiyun // Copyright (c) 2012 Samsung Electronics Co., Ltd
4*4882a593Smuzhiyun //              http://www.samsung.com
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #include <linux/module.h>
7*4882a593Smuzhiyun #include <linux/moduleparam.h>
8*4882a593Smuzhiyun #include <linux/init.h>
9*4882a593Smuzhiyun #include <linux/err.h>
10*4882a593Smuzhiyun #include <linux/slab.h>
11*4882a593Smuzhiyun #include <linux/i2c.h>
12*4882a593Smuzhiyun #include <linux/of.h>
13*4882a593Smuzhiyun #include <linux/of_irq.h>
14*4882a593Smuzhiyun #include <linux/interrupt.h>
15*4882a593Smuzhiyun #include <linux/pm_runtime.h>
16*4882a593Smuzhiyun #include <linux/mutex.h>
17*4882a593Smuzhiyun #include <linux/mfd/core.h>
18*4882a593Smuzhiyun #include <linux/mfd/samsung/core.h>
19*4882a593Smuzhiyun #include <linux/mfd/samsung/irq.h>
20*4882a593Smuzhiyun #include <linux/mfd/samsung/s2mpa01.h>
21*4882a593Smuzhiyun #include <linux/mfd/samsung/s2mps11.h>
22*4882a593Smuzhiyun #include <linux/mfd/samsung/s2mps13.h>
23*4882a593Smuzhiyun #include <linux/mfd/samsung/s2mps14.h>
24*4882a593Smuzhiyun #include <linux/mfd/samsung/s2mps15.h>
25*4882a593Smuzhiyun #include <linux/mfd/samsung/s2mpu02.h>
26*4882a593Smuzhiyun #include <linux/mfd/samsung/s5m8763.h>
27*4882a593Smuzhiyun #include <linux/mfd/samsung/s5m8767.h>
28*4882a593Smuzhiyun #include <linux/regmap.h>
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun static const struct mfd_cell s5m8751_devs[] = {
31*4882a593Smuzhiyun 	{ .name = "s5m8751-pmic", },
32*4882a593Smuzhiyun 	{ .name = "s5m-charger", },
33*4882a593Smuzhiyun 	{ .name = "s5m8751-codec", },
34*4882a593Smuzhiyun };
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun static const struct mfd_cell s5m8763_devs[] = {
37*4882a593Smuzhiyun 	{ .name = "s5m8763-pmic", },
38*4882a593Smuzhiyun 	{ .name = "s5m-rtc", },
39*4882a593Smuzhiyun 	{ .name = "s5m-charger", },
40*4882a593Smuzhiyun };
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun static const struct mfd_cell s5m8767_devs[] = {
43*4882a593Smuzhiyun 	{ .name = "s5m8767-pmic", },
44*4882a593Smuzhiyun 	{ .name = "s5m-rtc", },
45*4882a593Smuzhiyun 	{
46*4882a593Smuzhiyun 		.name = "s5m8767-clk",
47*4882a593Smuzhiyun 		.of_compatible = "samsung,s5m8767-clk",
48*4882a593Smuzhiyun 	},
49*4882a593Smuzhiyun };
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun static const struct mfd_cell s2mps11_devs[] = {
52*4882a593Smuzhiyun 	{ .name = "s2mps11-regulator", },
53*4882a593Smuzhiyun 	{ .name = "s2mps14-rtc", },
54*4882a593Smuzhiyun 	{
55*4882a593Smuzhiyun 		.name = "s2mps11-clk",
56*4882a593Smuzhiyun 		.of_compatible = "samsung,s2mps11-clk",
57*4882a593Smuzhiyun 	},
58*4882a593Smuzhiyun };
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun static const struct mfd_cell s2mps13_devs[] = {
61*4882a593Smuzhiyun 	{ .name = "s2mps13-regulator", },
62*4882a593Smuzhiyun 	{ .name = "s2mps13-rtc", },
63*4882a593Smuzhiyun 	{
64*4882a593Smuzhiyun 		.name = "s2mps13-clk",
65*4882a593Smuzhiyun 		.of_compatible = "samsung,s2mps13-clk",
66*4882a593Smuzhiyun 	},
67*4882a593Smuzhiyun };
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun static const struct mfd_cell s2mps14_devs[] = {
70*4882a593Smuzhiyun 	{ .name = "s2mps14-regulator", },
71*4882a593Smuzhiyun 	{ .name = "s2mps14-rtc", },
72*4882a593Smuzhiyun 	{
73*4882a593Smuzhiyun 		.name = "s2mps14-clk",
74*4882a593Smuzhiyun 		.of_compatible = "samsung,s2mps14-clk",
75*4882a593Smuzhiyun 	},
76*4882a593Smuzhiyun };
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun static const struct mfd_cell s2mps15_devs[] = {
79*4882a593Smuzhiyun 	{ .name = "s2mps15-regulator", },
80*4882a593Smuzhiyun 	{ .name = "s2mps15-rtc", },
81*4882a593Smuzhiyun 	{
82*4882a593Smuzhiyun 		.name = "s2mps13-clk",
83*4882a593Smuzhiyun 		.of_compatible = "samsung,s2mps13-clk",
84*4882a593Smuzhiyun 	},
85*4882a593Smuzhiyun };
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun static const struct mfd_cell s2mpa01_devs[] = {
88*4882a593Smuzhiyun 	{ .name = "s2mpa01-pmic", },
89*4882a593Smuzhiyun 	{ .name = "s2mps14-rtc", },
90*4882a593Smuzhiyun };
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun static const struct mfd_cell s2mpu02_devs[] = {
93*4882a593Smuzhiyun 	{ .name = "s2mpu02-regulator", },
94*4882a593Smuzhiyun };
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun #ifdef CONFIG_OF
97*4882a593Smuzhiyun static const struct of_device_id sec_dt_match[] = {
98*4882a593Smuzhiyun 	{
99*4882a593Smuzhiyun 		.compatible = "samsung,s5m8767-pmic",
100*4882a593Smuzhiyun 		.data = (void *)S5M8767X,
101*4882a593Smuzhiyun 	}, {
102*4882a593Smuzhiyun 		.compatible = "samsung,s2mps11-pmic",
103*4882a593Smuzhiyun 		.data = (void *)S2MPS11X,
104*4882a593Smuzhiyun 	}, {
105*4882a593Smuzhiyun 		.compatible = "samsung,s2mps13-pmic",
106*4882a593Smuzhiyun 		.data = (void *)S2MPS13X,
107*4882a593Smuzhiyun 	}, {
108*4882a593Smuzhiyun 		.compatible = "samsung,s2mps14-pmic",
109*4882a593Smuzhiyun 		.data = (void *)S2MPS14X,
110*4882a593Smuzhiyun 	}, {
111*4882a593Smuzhiyun 		.compatible = "samsung,s2mps15-pmic",
112*4882a593Smuzhiyun 		.data = (void *)S2MPS15X,
113*4882a593Smuzhiyun 	}, {
114*4882a593Smuzhiyun 		.compatible = "samsung,s2mpa01-pmic",
115*4882a593Smuzhiyun 		.data = (void *)S2MPA01,
116*4882a593Smuzhiyun 	}, {
117*4882a593Smuzhiyun 		.compatible = "samsung,s2mpu02-pmic",
118*4882a593Smuzhiyun 		.data = (void *)S2MPU02,
119*4882a593Smuzhiyun 	}, {
120*4882a593Smuzhiyun 		/* Sentinel */
121*4882a593Smuzhiyun 	},
122*4882a593Smuzhiyun };
123*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, sec_dt_match);
124*4882a593Smuzhiyun #endif
125*4882a593Smuzhiyun 
s2mpa01_volatile(struct device * dev,unsigned int reg)126*4882a593Smuzhiyun static bool s2mpa01_volatile(struct device *dev, unsigned int reg)
127*4882a593Smuzhiyun {
128*4882a593Smuzhiyun 	switch (reg) {
129*4882a593Smuzhiyun 	case S2MPA01_REG_INT1M:
130*4882a593Smuzhiyun 	case S2MPA01_REG_INT2M:
131*4882a593Smuzhiyun 	case S2MPA01_REG_INT3M:
132*4882a593Smuzhiyun 		return false;
133*4882a593Smuzhiyun 	default:
134*4882a593Smuzhiyun 		return true;
135*4882a593Smuzhiyun 	}
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun 
s2mps11_volatile(struct device * dev,unsigned int reg)138*4882a593Smuzhiyun static bool s2mps11_volatile(struct device *dev, unsigned int reg)
139*4882a593Smuzhiyun {
140*4882a593Smuzhiyun 	switch (reg) {
141*4882a593Smuzhiyun 	case S2MPS11_REG_INT1M:
142*4882a593Smuzhiyun 	case S2MPS11_REG_INT2M:
143*4882a593Smuzhiyun 	case S2MPS11_REG_INT3M:
144*4882a593Smuzhiyun 		return false;
145*4882a593Smuzhiyun 	default:
146*4882a593Smuzhiyun 		return true;
147*4882a593Smuzhiyun 	}
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun 
s2mpu02_volatile(struct device * dev,unsigned int reg)150*4882a593Smuzhiyun static bool s2mpu02_volatile(struct device *dev, unsigned int reg)
151*4882a593Smuzhiyun {
152*4882a593Smuzhiyun 	switch (reg) {
153*4882a593Smuzhiyun 	case S2MPU02_REG_INT1M:
154*4882a593Smuzhiyun 	case S2MPU02_REG_INT2M:
155*4882a593Smuzhiyun 	case S2MPU02_REG_INT3M:
156*4882a593Smuzhiyun 		return false;
157*4882a593Smuzhiyun 	default:
158*4882a593Smuzhiyun 		return true;
159*4882a593Smuzhiyun 	}
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun 
s5m8763_volatile(struct device * dev,unsigned int reg)162*4882a593Smuzhiyun static bool s5m8763_volatile(struct device *dev, unsigned int reg)
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun 	switch (reg) {
165*4882a593Smuzhiyun 	case S5M8763_REG_IRQM1:
166*4882a593Smuzhiyun 	case S5M8763_REG_IRQM2:
167*4882a593Smuzhiyun 	case S5M8763_REG_IRQM3:
168*4882a593Smuzhiyun 	case S5M8763_REG_IRQM4:
169*4882a593Smuzhiyun 		return false;
170*4882a593Smuzhiyun 	default:
171*4882a593Smuzhiyun 		return true;
172*4882a593Smuzhiyun 	}
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun static const struct regmap_config sec_regmap_config = {
176*4882a593Smuzhiyun 	.reg_bits = 8,
177*4882a593Smuzhiyun 	.val_bits = 8,
178*4882a593Smuzhiyun };
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun static const struct regmap_config s2mpa01_regmap_config = {
181*4882a593Smuzhiyun 	.reg_bits = 8,
182*4882a593Smuzhiyun 	.val_bits = 8,
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	.max_register = S2MPA01_REG_LDO_OVCB4,
185*4882a593Smuzhiyun 	.volatile_reg = s2mpa01_volatile,
186*4882a593Smuzhiyun 	.cache_type = REGCACHE_FLAT,
187*4882a593Smuzhiyun };
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun static const struct regmap_config s2mps11_regmap_config = {
190*4882a593Smuzhiyun 	.reg_bits = 8,
191*4882a593Smuzhiyun 	.val_bits = 8,
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 	.max_register = S2MPS11_REG_L38CTRL,
194*4882a593Smuzhiyun 	.volatile_reg = s2mps11_volatile,
195*4882a593Smuzhiyun 	.cache_type = REGCACHE_FLAT,
196*4882a593Smuzhiyun };
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun static const struct regmap_config s2mps13_regmap_config = {
199*4882a593Smuzhiyun 	.reg_bits = 8,
200*4882a593Smuzhiyun 	.val_bits = 8,
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 	.max_register = S2MPS13_REG_LDODSCH5,
203*4882a593Smuzhiyun 	.volatile_reg = s2mps11_volatile,
204*4882a593Smuzhiyun 	.cache_type = REGCACHE_FLAT,
205*4882a593Smuzhiyun };
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun static const struct regmap_config s2mps14_regmap_config = {
208*4882a593Smuzhiyun 	.reg_bits = 8,
209*4882a593Smuzhiyun 	.val_bits = 8,
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun 	.max_register = S2MPS14_REG_LDODSCH3,
212*4882a593Smuzhiyun 	.volatile_reg = s2mps11_volatile,
213*4882a593Smuzhiyun 	.cache_type = REGCACHE_FLAT,
214*4882a593Smuzhiyun };
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun static const struct regmap_config s2mps15_regmap_config = {
217*4882a593Smuzhiyun 	.reg_bits = 8,
218*4882a593Smuzhiyun 	.val_bits = 8,
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 	.max_register = S2MPS15_REG_LDODSCH4,
221*4882a593Smuzhiyun 	.volatile_reg = s2mps11_volatile,
222*4882a593Smuzhiyun 	.cache_type = REGCACHE_FLAT,
223*4882a593Smuzhiyun };
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun static const struct regmap_config s2mpu02_regmap_config = {
226*4882a593Smuzhiyun 	.reg_bits = 8,
227*4882a593Smuzhiyun 	.val_bits = 8,
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	.max_register = S2MPU02_REG_DVSDATA,
230*4882a593Smuzhiyun 	.volatile_reg = s2mpu02_volatile,
231*4882a593Smuzhiyun 	.cache_type = REGCACHE_FLAT,
232*4882a593Smuzhiyun };
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun static const struct regmap_config s5m8763_regmap_config = {
235*4882a593Smuzhiyun 	.reg_bits = 8,
236*4882a593Smuzhiyun 	.val_bits = 8,
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun 	.max_register = S5M8763_REG_LBCNFG2,
239*4882a593Smuzhiyun 	.volatile_reg = s5m8763_volatile,
240*4882a593Smuzhiyun 	.cache_type = REGCACHE_FLAT,
241*4882a593Smuzhiyun };
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun static const struct regmap_config s5m8767_regmap_config = {
244*4882a593Smuzhiyun 	.reg_bits = 8,
245*4882a593Smuzhiyun 	.val_bits = 8,
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	.max_register = S5M8767_REG_LDO28CTRL,
248*4882a593Smuzhiyun 	.volatile_reg = s2mps11_volatile,
249*4882a593Smuzhiyun 	.cache_type = REGCACHE_FLAT,
250*4882a593Smuzhiyun };
251*4882a593Smuzhiyun 
sec_pmic_dump_rev(struct sec_pmic_dev * sec_pmic)252*4882a593Smuzhiyun static void sec_pmic_dump_rev(struct sec_pmic_dev *sec_pmic)
253*4882a593Smuzhiyun {
254*4882a593Smuzhiyun 	unsigned int val;
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	/* For each device type, the REG_ID is always the first register */
257*4882a593Smuzhiyun 	if (!regmap_read(sec_pmic->regmap_pmic, S2MPS11_REG_ID, &val))
258*4882a593Smuzhiyun 		dev_dbg(sec_pmic->dev, "Revision: 0x%x\n", val);
259*4882a593Smuzhiyun }
260*4882a593Smuzhiyun 
sec_pmic_configure(struct sec_pmic_dev * sec_pmic)261*4882a593Smuzhiyun static void sec_pmic_configure(struct sec_pmic_dev *sec_pmic)
262*4882a593Smuzhiyun {
263*4882a593Smuzhiyun 	int err;
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 	if (sec_pmic->device_type != S2MPS13X)
266*4882a593Smuzhiyun 		return;
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	if (sec_pmic->pdata->disable_wrstbi) {
269*4882a593Smuzhiyun 		/*
270*4882a593Smuzhiyun 		 * If WRSTBI pin is pulled down this feature must be disabled
271*4882a593Smuzhiyun 		 * because each Suspend to RAM will trigger buck voltage reset
272*4882a593Smuzhiyun 		 * to default values.
273*4882a593Smuzhiyun 		 */
274*4882a593Smuzhiyun 		err = regmap_update_bits(sec_pmic->regmap_pmic,
275*4882a593Smuzhiyun 					 S2MPS13_REG_WRSTBI,
276*4882a593Smuzhiyun 					 S2MPS13_REG_WRSTBI_MASK, 0x0);
277*4882a593Smuzhiyun 		if (err)
278*4882a593Smuzhiyun 			dev_warn(sec_pmic->dev,
279*4882a593Smuzhiyun 				 "Cannot initialize WRSTBI config: %d\n",
280*4882a593Smuzhiyun 				 err);
281*4882a593Smuzhiyun 	}
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun #ifdef CONFIG_OF
285*4882a593Smuzhiyun /*
286*4882a593Smuzhiyun  * Only the common platform data elements for s5m8767 are parsed here from the
287*4882a593Smuzhiyun  * device tree. Other sub-modules of s5m8767 such as pmic, rtc , charger and
288*4882a593Smuzhiyun  * others have to parse their own platform data elements from device tree.
289*4882a593Smuzhiyun  *
290*4882a593Smuzhiyun  * The s5m8767 platform data structure is instantiated here and the drivers for
291*4882a593Smuzhiyun  * the sub-modules need not instantiate another instance while parsing their
292*4882a593Smuzhiyun  * platform data.
293*4882a593Smuzhiyun  */
294*4882a593Smuzhiyun static struct sec_platform_data *
sec_pmic_i2c_parse_dt_pdata(struct device * dev)295*4882a593Smuzhiyun sec_pmic_i2c_parse_dt_pdata(struct device *dev)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun 	struct sec_platform_data *pd;
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
300*4882a593Smuzhiyun 	if (!pd)
301*4882a593Smuzhiyun 		return ERR_PTR(-ENOMEM);
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	/*
304*4882a593Smuzhiyun 	 * ToDo: the 'wakeup' member in the platform data is more of a linux
305*4882a593Smuzhiyun 	 * specfic information. Hence, there is no binding for that yet and
306*4882a593Smuzhiyun 	 * not parsed here.
307*4882a593Smuzhiyun 	 */
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 	pd->manual_poweroff = of_property_read_bool(dev->of_node,
310*4882a593Smuzhiyun 						"samsung,s2mps11-acokb-ground");
311*4882a593Smuzhiyun 	pd->disable_wrstbi = of_property_read_bool(dev->of_node,
312*4882a593Smuzhiyun 						"samsung,s2mps11-wrstbi-ground");
313*4882a593Smuzhiyun 	return pd;
314*4882a593Smuzhiyun }
315*4882a593Smuzhiyun #else
316*4882a593Smuzhiyun static struct sec_platform_data *
sec_pmic_i2c_parse_dt_pdata(struct device * dev)317*4882a593Smuzhiyun sec_pmic_i2c_parse_dt_pdata(struct device *dev)
318*4882a593Smuzhiyun {
319*4882a593Smuzhiyun 	return NULL;
320*4882a593Smuzhiyun }
321*4882a593Smuzhiyun #endif
322*4882a593Smuzhiyun 
sec_i2c_get_driver_data(struct i2c_client * i2c,const struct i2c_device_id * id)323*4882a593Smuzhiyun static inline unsigned long sec_i2c_get_driver_data(struct i2c_client *i2c,
324*4882a593Smuzhiyun 						const struct i2c_device_id *id)
325*4882a593Smuzhiyun {
326*4882a593Smuzhiyun #ifdef CONFIG_OF
327*4882a593Smuzhiyun 	if (i2c->dev.of_node) {
328*4882a593Smuzhiyun 		const struct of_device_id *match;
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 		match = of_match_node(sec_dt_match, i2c->dev.of_node);
331*4882a593Smuzhiyun 		return (unsigned long)match->data;
332*4882a593Smuzhiyun 	}
333*4882a593Smuzhiyun #endif
334*4882a593Smuzhiyun 	return id->driver_data;
335*4882a593Smuzhiyun }
336*4882a593Smuzhiyun 
sec_pmic_probe(struct i2c_client * i2c,const struct i2c_device_id * id)337*4882a593Smuzhiyun static int sec_pmic_probe(struct i2c_client *i2c,
338*4882a593Smuzhiyun 			    const struct i2c_device_id *id)
339*4882a593Smuzhiyun {
340*4882a593Smuzhiyun 	struct sec_platform_data *pdata = dev_get_platdata(&i2c->dev);
341*4882a593Smuzhiyun 	const struct regmap_config *regmap;
342*4882a593Smuzhiyun 	const struct mfd_cell *sec_devs;
343*4882a593Smuzhiyun 	struct sec_pmic_dev *sec_pmic;
344*4882a593Smuzhiyun 	unsigned long device_type;
345*4882a593Smuzhiyun 	int ret, num_sec_devs;
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 	sec_pmic = devm_kzalloc(&i2c->dev, sizeof(struct sec_pmic_dev),
348*4882a593Smuzhiyun 				GFP_KERNEL);
349*4882a593Smuzhiyun 	if (sec_pmic == NULL)
350*4882a593Smuzhiyun 		return -ENOMEM;
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun 	i2c_set_clientdata(i2c, sec_pmic);
353*4882a593Smuzhiyun 	sec_pmic->dev = &i2c->dev;
354*4882a593Smuzhiyun 	sec_pmic->i2c = i2c;
355*4882a593Smuzhiyun 	sec_pmic->irq = i2c->irq;
356*4882a593Smuzhiyun 	device_type = sec_i2c_get_driver_data(i2c, id);
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun 	if (sec_pmic->dev->of_node) {
359*4882a593Smuzhiyun 		pdata = sec_pmic_i2c_parse_dt_pdata(sec_pmic->dev);
360*4882a593Smuzhiyun 		if (IS_ERR(pdata)) {
361*4882a593Smuzhiyun 			ret = PTR_ERR(pdata);
362*4882a593Smuzhiyun 			return ret;
363*4882a593Smuzhiyun 		}
364*4882a593Smuzhiyun 		pdata->device_type = device_type;
365*4882a593Smuzhiyun 	}
366*4882a593Smuzhiyun 	if (pdata) {
367*4882a593Smuzhiyun 		sec_pmic->device_type = pdata->device_type;
368*4882a593Smuzhiyun 		sec_pmic->irq_base = pdata->irq_base;
369*4882a593Smuzhiyun 		sec_pmic->wakeup = pdata->wakeup;
370*4882a593Smuzhiyun 		sec_pmic->pdata = pdata;
371*4882a593Smuzhiyun 	}
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 	switch (sec_pmic->device_type) {
374*4882a593Smuzhiyun 	case S2MPA01:
375*4882a593Smuzhiyun 		regmap = &s2mpa01_regmap_config;
376*4882a593Smuzhiyun 		break;
377*4882a593Smuzhiyun 	case S2MPS11X:
378*4882a593Smuzhiyun 		regmap = &s2mps11_regmap_config;
379*4882a593Smuzhiyun 		break;
380*4882a593Smuzhiyun 	case S2MPS13X:
381*4882a593Smuzhiyun 		regmap = &s2mps13_regmap_config;
382*4882a593Smuzhiyun 		break;
383*4882a593Smuzhiyun 	case S2MPS14X:
384*4882a593Smuzhiyun 		regmap = &s2mps14_regmap_config;
385*4882a593Smuzhiyun 		break;
386*4882a593Smuzhiyun 	case S2MPS15X:
387*4882a593Smuzhiyun 		regmap = &s2mps15_regmap_config;
388*4882a593Smuzhiyun 		break;
389*4882a593Smuzhiyun 	case S5M8763X:
390*4882a593Smuzhiyun 		regmap = &s5m8763_regmap_config;
391*4882a593Smuzhiyun 		break;
392*4882a593Smuzhiyun 	case S5M8767X:
393*4882a593Smuzhiyun 		regmap = &s5m8767_regmap_config;
394*4882a593Smuzhiyun 		break;
395*4882a593Smuzhiyun 	case S2MPU02:
396*4882a593Smuzhiyun 		regmap = &s2mpu02_regmap_config;
397*4882a593Smuzhiyun 		break;
398*4882a593Smuzhiyun 	default:
399*4882a593Smuzhiyun 		regmap = &sec_regmap_config;
400*4882a593Smuzhiyun 		break;
401*4882a593Smuzhiyun 	}
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 	sec_pmic->regmap_pmic = devm_regmap_init_i2c(i2c, regmap);
404*4882a593Smuzhiyun 	if (IS_ERR(sec_pmic->regmap_pmic)) {
405*4882a593Smuzhiyun 		ret = PTR_ERR(sec_pmic->regmap_pmic);
406*4882a593Smuzhiyun 		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
407*4882a593Smuzhiyun 			ret);
408*4882a593Smuzhiyun 		return ret;
409*4882a593Smuzhiyun 	}
410*4882a593Smuzhiyun 
411*4882a593Smuzhiyun 	if (pdata && pdata->cfg_pmic_irq)
412*4882a593Smuzhiyun 		pdata->cfg_pmic_irq();
413*4882a593Smuzhiyun 
414*4882a593Smuzhiyun 	sec_irq_init(sec_pmic);
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun 	pm_runtime_set_active(sec_pmic->dev);
417*4882a593Smuzhiyun 
418*4882a593Smuzhiyun 	switch (sec_pmic->device_type) {
419*4882a593Smuzhiyun 	case S5M8751X:
420*4882a593Smuzhiyun 		sec_devs = s5m8751_devs;
421*4882a593Smuzhiyun 		num_sec_devs = ARRAY_SIZE(s5m8751_devs);
422*4882a593Smuzhiyun 		break;
423*4882a593Smuzhiyun 	case S5M8763X:
424*4882a593Smuzhiyun 		sec_devs = s5m8763_devs;
425*4882a593Smuzhiyun 		num_sec_devs = ARRAY_SIZE(s5m8763_devs);
426*4882a593Smuzhiyun 		break;
427*4882a593Smuzhiyun 	case S5M8767X:
428*4882a593Smuzhiyun 		sec_devs = s5m8767_devs;
429*4882a593Smuzhiyun 		num_sec_devs = ARRAY_SIZE(s5m8767_devs);
430*4882a593Smuzhiyun 		break;
431*4882a593Smuzhiyun 	case S2MPA01:
432*4882a593Smuzhiyun 		sec_devs = s2mpa01_devs;
433*4882a593Smuzhiyun 		num_sec_devs = ARRAY_SIZE(s2mpa01_devs);
434*4882a593Smuzhiyun 		break;
435*4882a593Smuzhiyun 	case S2MPS11X:
436*4882a593Smuzhiyun 		sec_devs = s2mps11_devs;
437*4882a593Smuzhiyun 		num_sec_devs = ARRAY_SIZE(s2mps11_devs);
438*4882a593Smuzhiyun 		break;
439*4882a593Smuzhiyun 	case S2MPS13X:
440*4882a593Smuzhiyun 		sec_devs = s2mps13_devs;
441*4882a593Smuzhiyun 		num_sec_devs = ARRAY_SIZE(s2mps13_devs);
442*4882a593Smuzhiyun 		break;
443*4882a593Smuzhiyun 	case S2MPS14X:
444*4882a593Smuzhiyun 		sec_devs = s2mps14_devs;
445*4882a593Smuzhiyun 		num_sec_devs = ARRAY_SIZE(s2mps14_devs);
446*4882a593Smuzhiyun 		break;
447*4882a593Smuzhiyun 	case S2MPS15X:
448*4882a593Smuzhiyun 		sec_devs = s2mps15_devs;
449*4882a593Smuzhiyun 		num_sec_devs = ARRAY_SIZE(s2mps15_devs);
450*4882a593Smuzhiyun 		break;
451*4882a593Smuzhiyun 	case S2MPU02:
452*4882a593Smuzhiyun 		sec_devs = s2mpu02_devs;
453*4882a593Smuzhiyun 		num_sec_devs = ARRAY_SIZE(s2mpu02_devs);
454*4882a593Smuzhiyun 		break;
455*4882a593Smuzhiyun 	default:
456*4882a593Smuzhiyun 		dev_err(&i2c->dev, "Unsupported device type (%lu)\n",
457*4882a593Smuzhiyun 			sec_pmic->device_type);
458*4882a593Smuzhiyun 		return -ENODEV;
459*4882a593Smuzhiyun 	}
460*4882a593Smuzhiyun 	ret = devm_mfd_add_devices(sec_pmic->dev, -1, sec_devs, num_sec_devs,
461*4882a593Smuzhiyun 				   NULL, 0, NULL);
462*4882a593Smuzhiyun 	if (ret)
463*4882a593Smuzhiyun 		return ret;
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun 	device_init_wakeup(sec_pmic->dev, sec_pmic->wakeup);
466*4882a593Smuzhiyun 	sec_pmic_configure(sec_pmic);
467*4882a593Smuzhiyun 	sec_pmic_dump_rev(sec_pmic);
468*4882a593Smuzhiyun 
469*4882a593Smuzhiyun 	return ret;
470*4882a593Smuzhiyun }
471*4882a593Smuzhiyun 
sec_pmic_shutdown(struct i2c_client * i2c)472*4882a593Smuzhiyun static void sec_pmic_shutdown(struct i2c_client *i2c)
473*4882a593Smuzhiyun {
474*4882a593Smuzhiyun 	struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
475*4882a593Smuzhiyun 	unsigned int reg, mask;
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun 	if (!sec_pmic->pdata->manual_poweroff)
478*4882a593Smuzhiyun 		return;
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun 	switch (sec_pmic->device_type) {
481*4882a593Smuzhiyun 	case S2MPS11X:
482*4882a593Smuzhiyun 		reg = S2MPS11_REG_CTRL1;
483*4882a593Smuzhiyun 		mask = S2MPS11_CTRL1_PWRHOLD_MASK;
484*4882a593Smuzhiyun 		break;
485*4882a593Smuzhiyun 	default:
486*4882a593Smuzhiyun 		/*
487*4882a593Smuzhiyun 		 * Currently only one board with S2MPS11 needs this, so just
488*4882a593Smuzhiyun 		 * ignore the rest.
489*4882a593Smuzhiyun 		 */
490*4882a593Smuzhiyun 		dev_warn(sec_pmic->dev,
491*4882a593Smuzhiyun 			"Unsupported device %lu for manual power off\n",
492*4882a593Smuzhiyun 			sec_pmic->device_type);
493*4882a593Smuzhiyun 		return;
494*4882a593Smuzhiyun 	}
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun 	regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, 0);
497*4882a593Smuzhiyun }
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
sec_pmic_suspend(struct device * dev)500*4882a593Smuzhiyun static int sec_pmic_suspend(struct device *dev)
501*4882a593Smuzhiyun {
502*4882a593Smuzhiyun 	struct i2c_client *i2c = to_i2c_client(dev);
503*4882a593Smuzhiyun 	struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun 	if (device_may_wakeup(dev))
506*4882a593Smuzhiyun 		enable_irq_wake(sec_pmic->irq);
507*4882a593Smuzhiyun 	/*
508*4882a593Smuzhiyun 	 * PMIC IRQ must be disabled during suspend for RTC alarm
509*4882a593Smuzhiyun 	 * to work properly.
510*4882a593Smuzhiyun 	 * When device is woken up from suspend, an
511*4882a593Smuzhiyun 	 * interrupt occurs before resuming I2C bus controller.
512*4882a593Smuzhiyun 	 * The interrupt is handled by regmap_irq_thread which tries
513*4882a593Smuzhiyun 	 * to read RTC registers. This read fails (I2C is still
514*4882a593Smuzhiyun 	 * suspended) and RTC Alarm interrupt is disabled.
515*4882a593Smuzhiyun 	 */
516*4882a593Smuzhiyun 	disable_irq(sec_pmic->irq);
517*4882a593Smuzhiyun 
518*4882a593Smuzhiyun 	return 0;
519*4882a593Smuzhiyun }
520*4882a593Smuzhiyun 
sec_pmic_resume(struct device * dev)521*4882a593Smuzhiyun static int sec_pmic_resume(struct device *dev)
522*4882a593Smuzhiyun {
523*4882a593Smuzhiyun 	struct i2c_client *i2c = to_i2c_client(dev);
524*4882a593Smuzhiyun 	struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
525*4882a593Smuzhiyun 
526*4882a593Smuzhiyun 	if (device_may_wakeup(dev))
527*4882a593Smuzhiyun 		disable_irq_wake(sec_pmic->irq);
528*4882a593Smuzhiyun 	enable_irq(sec_pmic->irq);
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun 	return 0;
531*4882a593Smuzhiyun }
532*4882a593Smuzhiyun #endif /* CONFIG_PM_SLEEP */
533*4882a593Smuzhiyun 
534*4882a593Smuzhiyun static SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops, sec_pmic_suspend, sec_pmic_resume);
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun static const struct i2c_device_id sec_pmic_id[] = {
537*4882a593Smuzhiyun 	{ "sec_pmic", 0 },
538*4882a593Smuzhiyun 	{ }
539*4882a593Smuzhiyun };
540*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, sec_pmic_id);
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun static struct i2c_driver sec_pmic_driver = {
543*4882a593Smuzhiyun 	.driver = {
544*4882a593Smuzhiyun 		   .name = "sec_pmic",
545*4882a593Smuzhiyun 		   .pm = &sec_pmic_pm_ops,
546*4882a593Smuzhiyun 		   .of_match_table = of_match_ptr(sec_dt_match),
547*4882a593Smuzhiyun 	},
548*4882a593Smuzhiyun 	.probe = sec_pmic_probe,
549*4882a593Smuzhiyun 	.shutdown = sec_pmic_shutdown,
550*4882a593Smuzhiyun 	.id_table = sec_pmic_id,
551*4882a593Smuzhiyun };
552*4882a593Smuzhiyun 
sec_pmic_init(void)553*4882a593Smuzhiyun static int __init sec_pmic_init(void)
554*4882a593Smuzhiyun {
555*4882a593Smuzhiyun 	return i2c_add_driver(&sec_pmic_driver);
556*4882a593Smuzhiyun }
557*4882a593Smuzhiyun 
558*4882a593Smuzhiyun subsys_initcall(sec_pmic_init);
559*4882a593Smuzhiyun 
sec_pmic_exit(void)560*4882a593Smuzhiyun static void __exit sec_pmic_exit(void)
561*4882a593Smuzhiyun {
562*4882a593Smuzhiyun 	i2c_del_driver(&sec_pmic_driver);
563*4882a593Smuzhiyun }
564*4882a593Smuzhiyun module_exit(sec_pmic_exit);
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
567*4882a593Smuzhiyun MODULE_DESCRIPTION("Core support for the S5M MFD");
568*4882a593Smuzhiyun MODULE_LICENSE("GPL");
569