xref: /linux/drivers/mfd/rk8xx-core.c (revision 1fd1dc41724319406b0aff221a352a400b0ddfc5)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * MFD core driver for Rockchip RK8XX
4  *
5  * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
6  * Copyright (C) 2016 PHYTEC Messtechnik GmbH
7  *
8  * Author: Chris Zhong <zyw@rock-chips.com>
9  * Author: Zhang Qing <zhangqing@rock-chips.com>
10  * Author: Wadim Egorov <w.egorov@phytec.de>
11  */
12 
13 #include <linux/bitfield.h>
14 #include <linux/interrupt.h>
15 #include <linux/mfd/rk808.h>
16 #include <linux/mfd/core.h>
17 #include <linux/module.h>
18 #include <linux/property.h>
19 #include <linux/regmap.h>
20 #include <linux/reboot.h>
21 
22 struct rk808_reg_data {
23 	int addr;
24 	int mask;
25 	int value;
26 };
27 
28 static const struct resource rtc_resources[] = {
29 	DEFINE_RES_IRQ(RK808_IRQ_RTC_ALARM),
30 };
31 
32 static const struct resource rk816_rtc_resources[] = {
33 	DEFINE_RES_IRQ(RK816_IRQ_RTC_ALARM),
34 };
35 
36 static const struct resource rk817_rtc_resources[] = {
37 	DEFINE_RES_IRQ(RK817_IRQ_RTC_ALARM),
38 };
39 
40 static const struct resource rk801_key_resources[] = {
41 	DEFINE_RES_IRQ(RK801_IRQ_PWRON_FALL),
42 	DEFINE_RES_IRQ(RK801_IRQ_PWRON_RISE),
43 };
44 
45 static const struct resource rk805_key_resources[] = {
46 	DEFINE_RES_IRQ(RK805_IRQ_PWRON_RISE),
47 	DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL),
48 };
49 
50 static struct resource rk806_pwrkey_resources[] = {
51 	DEFINE_RES_IRQ(RK806_IRQ_PWRON_FALL),
52 	DEFINE_RES_IRQ(RK806_IRQ_PWRON_RISE),
53 };
54 
55 static const struct resource rk817_pwrkey_resources[] = {
56 	DEFINE_RES_IRQ(RK817_IRQ_PWRON_FALL),
57 	DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE),
58 };
59 
60 static const struct resource rk817_charger_resources[] = {
61 	DEFINE_RES_IRQ(RK817_IRQ_PLUG_IN),
62 	DEFINE_RES_IRQ(RK817_IRQ_PLUG_OUT),
63 };
64 
65 static const struct mfd_cell rk801s[] = {
66 	{ .name = "rk808-regulator", },
67 	{	.name = "rk805-pwrkey",
68 		.num_resources = ARRAY_SIZE(rk801_key_resources),
69 		.resources = &rk801_key_resources[0],
70 	},
71 };
72 
73 static const struct mfd_cell rk805s[] = {
74 	{ .name = "rk808-clkout", },
75 	{ .name = "rk808-regulator", },
76 	{ .name = "rk805-pinctrl", },
77 	{
78 		.name = "rk808-rtc",
79 		.num_resources = ARRAY_SIZE(rtc_resources),
80 		.resources = &rtc_resources[0],
81 	},
82 	{	.name = "rk805-pwrkey",
83 		.num_resources = ARRAY_SIZE(rk805_key_resources),
84 		.resources = &rk805_key_resources[0],
85 	},
86 };
87 
88 static const struct mfd_cell rk806s[] = {
89 	{ .name = "rk805-pinctrl", },
90 	{ .name = "rk808-regulator", },
91 	{
92 		.name = "rk805-pwrkey",
93 		.resources = rk806_pwrkey_resources,
94 		.num_resources = ARRAY_SIZE(rk806_pwrkey_resources),
95 	},
96 };
97 
98 static const struct mfd_cell rk808s[] = {
99 	{ .name = "rk808-clkout", },
100 	{ .name = "rk808-regulator", },
101 	{
102 		.name = "rk808-rtc",
103 		.num_resources = ARRAY_SIZE(rtc_resources),
104 		.resources = rtc_resources,
105 	},
106 };
107 
108 static const struct mfd_cell rk816s[] = {
109 	{ .name = "rk805-pinctrl", },
110 	{ .name = "rk808-clkout", },
111 	{ .name = "rk808-regulator", },
112 	{
113 		.name = "rk805-pwrkey",
114 		.num_resources = ARRAY_SIZE(rk805_key_resources),
115 		.resources = rk805_key_resources,
116 	},
117 	{
118 		.name = "rk808-rtc",
119 		.num_resources = ARRAY_SIZE(rk816_rtc_resources),
120 		.resources = rk816_rtc_resources,
121 	},
122 };
123 
124 static const struct mfd_cell rk817s[] = {
125 	{ .name = "rk808-clkout", },
126 	{ .name = "rk808-regulator", },
127 	{
128 		.name = "rk805-pwrkey",
129 		.num_resources = ARRAY_SIZE(rk817_pwrkey_resources),
130 		.resources = &rk817_pwrkey_resources[0],
131 	},
132 	{
133 		.name = "rk808-rtc",
134 		.num_resources = ARRAY_SIZE(rk817_rtc_resources),
135 		.resources = &rk817_rtc_resources[0],
136 	},
137 	{ .name = "rk817-codec", },
138 	{
139 		.name = "rk817-charger",
140 		.num_resources = ARRAY_SIZE(rk817_charger_resources),
141 		.resources = &rk817_charger_resources[0],
142 	},
143 };
144 
145 static const struct mfd_cell rk818s[] = {
146 	{ .name = "rk808-clkout", },
147 	{ .name = "rk808-regulator", },
148 	{
149 		.name = "rk808-rtc",
150 		.num_resources = ARRAY_SIZE(rtc_resources),
151 		.resources = rtc_resources,
152 	},
153 };
154 
155 static const struct rk808_reg_data rk801_pre_init_reg[] = {
156 	{ RK801_SLEEP_CFG_REG, RK801_SLEEP_FUN_MSK, RK801_NONE_FUN },
157 	{ RK801_SYS_CFG2_REG, RK801_RST_MSK, RK801_RST_RESTART_REG_RESETB },
158 	{ RK801_INT_CONFIG_REG, RK801_INT_POL_MSK, RK801_INT_ACT_L },
159 	{ RK801_POWER_FPWM_EN_REG, RK801_PLDO_HRDEC_EN, RK801_PLDO_HRDEC_EN },
160 	{ RK801_BUCK_DEBUG5_REG, MASK_ALL, 0x54 },
161 	{ RK801_CON_BACK1_REG, MASK_ALL, 0x18 },
162 };
163 
164 static const struct rk808_reg_data rk805_pre_init_reg[] = {
165 	{RK805_BUCK1_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
166 				 RK805_BUCK1_2_ILMAX_4000MA},
167 	{RK805_BUCK2_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
168 				 RK805_BUCK1_2_ILMAX_4000MA},
169 	{RK805_BUCK3_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK,
170 				 RK805_BUCK3_ILMAX_3000MA},
171 	{RK805_BUCK4_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK,
172 				 RK805_BUCK4_ILMAX_3500MA},
173 	{RK805_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_400MA},
174 	{RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C},
175 };
176 
177 static const struct rk808_reg_data rk806_pre_init_reg[] = {
178 	{ RK806_GPIO_INT_CONFIG, RK806_INT_POL_MSK, RK806_INT_POL_L },
179 	{ RK806_SYS_CFG3, RK806_SLAVE_RESTART_FUN_MSK, RK806_SLAVE_RESTART_FUN_EN },
180 	{ RK806_SYS_OPTION, RK806_SYS_ENB2_2M_MSK, RK806_SYS_ENB2_2M_EN },
181 };
182 
183 static const struct rk808_reg_data rk808_pre_init_reg[] = {
184 	{ RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_150MA },
185 	{ RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_200MA },
186 	{ RK808_BOOST_CONFIG_REG, BOOST_ILMIN_MASK, BOOST_ILMIN_100MA },
187 	{ RK808_BUCK1_CONFIG_REG, BUCK1_RATE_MASK,  BUCK_ILMIN_200MA },
188 	{ RK808_BUCK2_CONFIG_REG, BUCK2_RATE_MASK,  BUCK_ILMIN_200MA },
189 	{ RK808_DCDC_UV_ACT_REG,  BUCK_UV_ACT_MASK, BUCK_UV_ACT_DISABLE},
190 	{ RK808_VB_MON_REG,       MASK_ALL,         VB_LO_ACT |
191 						    VB_LO_SEL_3500MV },
192 };
193 
194 static const struct rk808_reg_data rk816_pre_init_reg[] = {
195 	{ RK818_BUCK1_CONFIG_REG, RK817_RAMP_RATE_MASK,
196 				  RK817_RAMP_RATE_12_5MV_PER_US },
197 	{ RK818_BUCK2_CONFIG_REG, RK817_RAMP_RATE_MASK,
198 				  RK817_RAMP_RATE_12_5MV_PER_US },
199 	{ RK818_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_250MA },
200 	{ RK808_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP105C},
201 	{ RK808_VB_MON_REG, VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK,
202 			    RK808_VBAT_LOW_3V0 | EN_VABT_LOW_SHUT_DOWN },
203 };
204 
205 static const struct rk808_reg_data rk817_pre_init_reg[] = {
206 	{RK817_RTC_CTRL_REG, RTC_STOP, RTC_STOP},
207 	/* Codec specific registers */
208 	{ RK817_CODEC_DTOP_VUCTL, MASK_ALL, 0x03 },
209 	{ RK817_CODEC_DTOP_VUCTIME, MASK_ALL, 0x00 },
210 	{ RK817_CODEC_DTOP_LPT_SRST, MASK_ALL, 0x00 },
211 	{ RK817_CODEC_DTOP_DIGEN_CLKE, MASK_ALL, 0x00 },
212 	/* from vendor driver, CODEC_AREF_RTCFG0 not defined in data sheet */
213 	{ RK817_CODEC_AREF_RTCFG0, MASK_ALL, 0x00 },
214 	{ RK817_CODEC_AREF_RTCFG1, MASK_ALL, 0x06 },
215 	{ RK817_CODEC_AADC_CFG0, MASK_ALL, 0xc8 },
216 	/* from vendor driver, CODEC_AADC_CFG1 not defined in data sheet */
217 	{ RK817_CODEC_AADC_CFG1, MASK_ALL, 0x00 },
218 	{ RK817_CODEC_DADC_VOLL, MASK_ALL, 0x00 },
219 	{ RK817_CODEC_DADC_VOLR, MASK_ALL, 0x00 },
220 	{ RK817_CODEC_DADC_SR_ACL0, MASK_ALL, 0x00 },
221 	{ RK817_CODEC_DADC_ALC1, MASK_ALL, 0x00 },
222 	{ RK817_CODEC_DADC_ALC2, MASK_ALL, 0x00 },
223 	{ RK817_CODEC_DADC_NG, MASK_ALL, 0x00 },
224 	{ RK817_CODEC_DADC_HPF, MASK_ALL, 0x00 },
225 	{ RK817_CODEC_DADC_RVOLL, MASK_ALL, 0xff },
226 	{ RK817_CODEC_DADC_RVOLR, MASK_ALL, 0xff },
227 	{ RK817_CODEC_AMIC_CFG0, MASK_ALL, 0x70 },
228 	{ RK817_CODEC_AMIC_CFG1, MASK_ALL, 0x00 },
229 	{ RK817_CODEC_DMIC_PGA_GAIN, MASK_ALL, 0x66 },
230 	{ RK817_CODEC_DMIC_LMT1, MASK_ALL, 0x00 },
231 	{ RK817_CODEC_DMIC_LMT2, MASK_ALL, 0x00 },
232 	{ RK817_CODEC_DMIC_NG1, MASK_ALL, 0x00 },
233 	{ RK817_CODEC_DMIC_NG2, MASK_ALL, 0x00 },
234 	/* from vendor driver, CODEC_ADAC_CFG0 not defined in data sheet */
235 	{ RK817_CODEC_ADAC_CFG0, MASK_ALL, 0x00 },
236 	{ RK817_CODEC_ADAC_CFG1, MASK_ALL, 0x07 },
237 	{ RK817_CODEC_DDAC_POPD_DACST, MASK_ALL, 0x82 },
238 	{ RK817_CODEC_DDAC_VOLL, MASK_ALL, 0x00 },
239 	{ RK817_CODEC_DDAC_VOLR, MASK_ALL, 0x00 },
240 	{ RK817_CODEC_DDAC_SR_LMT0, MASK_ALL, 0x00 },
241 	{ RK817_CODEC_DDAC_LMT1, MASK_ALL, 0x00 },
242 	{ RK817_CODEC_DDAC_LMT2, MASK_ALL, 0x00 },
243 	{ RK817_CODEC_DDAC_MUTE_MIXCTL, MASK_ALL, 0xa0 },
244 	{ RK817_CODEC_DDAC_RVOLL, MASK_ALL, 0xff },
245 	{ RK817_CODEC_DADC_RVOLR, MASK_ALL, 0xff },
246 	{ RK817_CODEC_AMIC_CFG0, MASK_ALL, 0x70 },
247 	{ RK817_CODEC_AMIC_CFG1, MASK_ALL, 0x00 },
248 	{ RK817_CODEC_DMIC_PGA_GAIN, MASK_ALL, 0x66 },
249 	{ RK817_CODEC_DMIC_LMT1, MASK_ALL, 0x00 },
250 	{ RK817_CODEC_DMIC_LMT2, MASK_ALL, 0x00 },
251 	{ RK817_CODEC_DMIC_NG1, MASK_ALL, 0x00 },
252 	{ RK817_CODEC_DMIC_NG2, MASK_ALL, 0x00 },
253 	/* from vendor driver, CODEC_ADAC_CFG0 not defined in data sheet */
254 	{ RK817_CODEC_ADAC_CFG0, MASK_ALL, 0x00 },
255 	{ RK817_CODEC_ADAC_CFG1, MASK_ALL, 0x07 },
256 	{ RK817_CODEC_DDAC_POPD_DACST, MASK_ALL, 0x82 },
257 	{ RK817_CODEC_DDAC_VOLL, MASK_ALL, 0x00 },
258 	{ RK817_CODEC_DDAC_VOLR, MASK_ALL, 0x00 },
259 	{ RK817_CODEC_DDAC_SR_LMT0, MASK_ALL, 0x00 },
260 	{ RK817_CODEC_DDAC_LMT1, MASK_ALL, 0x00 },
261 	{ RK817_CODEC_DDAC_LMT2, MASK_ALL, 0x00 },
262 	{ RK817_CODEC_DDAC_MUTE_MIXCTL, MASK_ALL, 0xa0 },
263 	{ RK817_CODEC_DDAC_RVOLL, MASK_ALL, 0xff },
264 	{ RK817_CODEC_DDAC_RVOLR, MASK_ALL, 0xff },
265 	{ RK817_CODEC_AHP_ANTI0, MASK_ALL, 0x00 },
266 	{ RK817_CODEC_AHP_ANTI1, MASK_ALL, 0x00 },
267 	{ RK817_CODEC_AHP_CFG0, MASK_ALL, 0xe0 },
268 	{ RK817_CODEC_AHP_CFG1, MASK_ALL, 0x1f },
269 	{ RK817_CODEC_AHP_CP, MASK_ALL, 0x09 },
270 	{ RK817_CODEC_ACLASSD_CFG1, MASK_ALL, 0x69 },
271 	{ RK817_CODEC_ACLASSD_CFG2, MASK_ALL, 0x44 },
272 	{ RK817_CODEC_APLL_CFG0, MASK_ALL, 0x04 },
273 	{ RK817_CODEC_APLL_CFG1, MASK_ALL, 0x00 },
274 	{ RK817_CODEC_APLL_CFG2, MASK_ALL, 0x30 },
275 	{ RK817_CODEC_APLL_CFG3, MASK_ALL, 0x19 },
276 	{ RK817_CODEC_APLL_CFG4, MASK_ALL, 0x65 },
277 	{ RK817_CODEC_APLL_CFG5, MASK_ALL, 0x01 },
278 	{ RK817_CODEC_DI2S_CKM, MASK_ALL, 0x01 },
279 	{ RK817_CODEC_DI2S_RSD, MASK_ALL, 0x00 },
280 	{ RK817_CODEC_DI2S_RXCR1, MASK_ALL, 0x00 },
281 	{ RK817_CODEC_DI2S_RXCR2, MASK_ALL, 0x17 },
282 	{ RK817_CODEC_DI2S_RXCMD_TSD, MASK_ALL, 0x00 },
283 	{ RK817_CODEC_DI2S_TXCR1, MASK_ALL, 0x00 },
284 	{ RK817_CODEC_DI2S_TXCR2, MASK_ALL, 0x17 },
285 	{ RK817_CODEC_DI2S_TXCR3_TXCMD, MASK_ALL, 0x00 },
286 	{RK817_GPIO_INT_CFG, RK817_INT_POL_MSK, RK817_INT_POL_L},
287 	{RK817_SYS_CFG(1), RK817_HOTDIE_TEMP_MSK | RK817_TSD_TEMP_MSK,
288 					   RK817_HOTDIE_105 | RK817_TSD_140},
289 };
290 
291 static const struct rk808_reg_data rk818_pre_init_reg[] = {
292 	/* improve efficiency */
293 	{ RK818_BUCK2_CONFIG_REG, BUCK2_RATE_MASK,  BUCK_ILMIN_250MA },
294 	{ RK818_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_250MA },
295 	{ RK818_BOOST_CONFIG_REG, BOOST_ILMIN_MASK, BOOST_ILMIN_100MA },
296 	{ RK818_USB_CTRL_REG,	  RK818_USB_ILIM_SEL_MASK,
297 						    RK818_USB_ILMIN_2000MA },
298 	/* close charger when usb lower then 3.4V */
299 	{ RK818_USB_CTRL_REG,	  RK818_USB_CHG_SD_VSEL_MASK,
300 						    (0x7 << 4) },
301 	/* no action when vref */
302 	{ RK818_H5V_EN_REG,	  BIT(1),	    RK818_REF_RDY_CTRL },
303 	/* enable HDMI 5V */
304 	{ RK818_H5V_EN_REG,	  BIT(0),	    RK818_H5V_EN },
305 	{ RK808_VB_MON_REG,	  MASK_ALL,	    VB_LO_ACT |
306 						    VB_LO_SEL_3500MV },
307 };
308 
309 static const struct regmap_irq rk801_irqs[] = {
310 	[RK801_IRQ_PWRON_FALL] = {
311 		.mask = RK801_IRQ_PWRON_FALL_MSK,
312 		.reg_offset = 0,
313 	},
314 	[RK801_IRQ_PWRON_RISE] = {
315 		.mask = RK801_IRQ_PWRON_RISE_MSK,
316 		.reg_offset = 0,
317 	},
318 	[RK801_IRQ_PWRON] = {
319 		.mask = RK801_IRQ_PWRON_MSK,
320 		.reg_offset = 0,
321 	},
322 	[RK801_IRQ_PWRON_LP] = {
323 		.mask = RK801_IRQ_PWRON_LP_MSK,
324 		.reg_offset = 0,
325 	},
326 	[RK801_IRQ_HOTDIE] = {
327 		.mask = RK801_IRQ_HOTDIE_MSK,
328 		.reg_offset = 0,
329 	},
330 	[RK801_IRQ_VDC_RISE] = {
331 		.mask = RK801_IRQ_VDC_RISE_MSK,
332 		.reg_offset = 0,
333 	},
334 	[RK801_IRQ_VDC_FALL] = {
335 		.mask = RK801_IRQ_VDC_FALL_MSK,
336 		.reg_offset = 0,
337 	},
338 };
339 
340 static const struct regmap_irq rk805_irqs[] = {
341 	[RK805_IRQ_PWRON_RISE] = {
342 		.mask = RK805_IRQ_PWRON_RISE_MSK,
343 		.reg_offset = 0,
344 	},
345 	[RK805_IRQ_VB_LOW] = {
346 		.mask = RK805_IRQ_VB_LOW_MSK,
347 		.reg_offset = 0,
348 	},
349 	[RK805_IRQ_PWRON] = {
350 		.mask = RK805_IRQ_PWRON_MSK,
351 		.reg_offset = 0,
352 	},
353 	[RK805_IRQ_PWRON_LP] = {
354 		.mask = RK805_IRQ_PWRON_LP_MSK,
355 		.reg_offset = 0,
356 	},
357 	[RK805_IRQ_HOTDIE] = {
358 		.mask = RK805_IRQ_HOTDIE_MSK,
359 		.reg_offset = 0,
360 	},
361 	[RK805_IRQ_RTC_ALARM] = {
362 		.mask = RK805_IRQ_RTC_ALARM_MSK,
363 		.reg_offset = 0,
364 	},
365 	[RK805_IRQ_RTC_PERIOD] = {
366 		.mask = RK805_IRQ_RTC_PERIOD_MSK,
367 		.reg_offset = 0,
368 	},
369 	[RK805_IRQ_PWRON_FALL] = {
370 		.mask = RK805_IRQ_PWRON_FALL_MSK,
371 		.reg_offset = 0,
372 	},
373 };
374 
375 static const struct regmap_irq rk806_irqs[] = {
376 	/* INT_STS0 IRQs */
377 	REGMAP_IRQ_REG(RK806_IRQ_PWRON_FALL, 0, RK806_INT_STS_PWRON_FALL),
378 	REGMAP_IRQ_REG(RK806_IRQ_PWRON_RISE, 0, RK806_INT_STS_PWRON_RISE),
379 	REGMAP_IRQ_REG(RK806_IRQ_PWRON, 0, RK806_INT_STS_PWRON),
380 	REGMAP_IRQ_REG(RK806_IRQ_PWRON_LP, 0, RK806_INT_STS_PWRON_LP),
381 	REGMAP_IRQ_REG(RK806_IRQ_HOTDIE, 0, RK806_INT_STS_HOTDIE),
382 	REGMAP_IRQ_REG(RK806_IRQ_VDC_RISE, 0, RK806_INT_STS_VDC_RISE),
383 	REGMAP_IRQ_REG(RK806_IRQ_VDC_FALL, 0, RK806_INT_STS_VDC_FALL),
384 	REGMAP_IRQ_REG(RK806_IRQ_VB_LO, 0, RK806_INT_STS_VB_LO),
385 	/* INT_STS1 IRQs */
386 	REGMAP_IRQ_REG(RK806_IRQ_REV0, 1, RK806_INT_STS_REV0),
387 	REGMAP_IRQ_REG(RK806_IRQ_REV1, 1, RK806_INT_STS_REV1),
388 	REGMAP_IRQ_REG(RK806_IRQ_REV2, 1, RK806_INT_STS_REV2),
389 	REGMAP_IRQ_REG(RK806_IRQ_CRC_ERROR, 1, RK806_INT_STS_CRC_ERROR),
390 	REGMAP_IRQ_REG(RK806_IRQ_SLP3_GPIO, 1, RK806_INT_STS_SLP3_GPIO),
391 	REGMAP_IRQ_REG(RK806_IRQ_SLP2_GPIO, 1, RK806_INT_STS_SLP2_GPIO),
392 	REGMAP_IRQ_REG(RK806_IRQ_SLP1_GPIO, 1, RK806_INT_STS_SLP1_GPIO),
393 	REGMAP_IRQ_REG(RK806_IRQ_WDT, 1, RK806_INT_STS_WDT),
394 };
395 
396 static const struct regmap_irq rk808_irqs[] = {
397 	/* INT_STS */
398 	[RK808_IRQ_VOUT_LO] = {
399 		.mask = RK808_IRQ_VOUT_LO_MSK,
400 		.reg_offset = 0,
401 	},
402 	[RK808_IRQ_VB_LO] = {
403 		.mask = RK808_IRQ_VB_LO_MSK,
404 		.reg_offset = 0,
405 	},
406 	[RK808_IRQ_PWRON] = {
407 		.mask = RK808_IRQ_PWRON_MSK,
408 		.reg_offset = 0,
409 	},
410 	[RK808_IRQ_PWRON_LP] = {
411 		.mask = RK808_IRQ_PWRON_LP_MSK,
412 		.reg_offset = 0,
413 	},
414 	[RK808_IRQ_HOTDIE] = {
415 		.mask = RK808_IRQ_HOTDIE_MSK,
416 		.reg_offset = 0,
417 	},
418 	[RK808_IRQ_RTC_ALARM] = {
419 		.mask = RK808_IRQ_RTC_ALARM_MSK,
420 		.reg_offset = 0,
421 	},
422 	[RK808_IRQ_RTC_PERIOD] = {
423 		.mask = RK808_IRQ_RTC_PERIOD_MSK,
424 		.reg_offset = 0,
425 	},
426 
427 	/* INT_STS2 */
428 	[RK808_IRQ_PLUG_IN_INT] = {
429 		.mask = RK808_IRQ_PLUG_IN_INT_MSK,
430 		.reg_offset = 1,
431 	},
432 	[RK808_IRQ_PLUG_OUT_INT] = {
433 		.mask = RK808_IRQ_PLUG_OUT_INT_MSK,
434 		.reg_offset = 1,
435 	},
436 };
437 
438 static const unsigned int rk816_irq_status_offsets[] = {
439 	RK816_IRQ_STS_OFFSET(RK816_INT_STS_REG1),
440 	RK816_IRQ_STS_OFFSET(RK816_INT_STS_REG2),
441 	RK816_IRQ_STS_OFFSET(RK816_INT_STS_REG3),
442 };
443 
444 static const unsigned int rk816_irq_mask_offsets[] = {
445 	RK816_IRQ_MSK_OFFSET(RK816_INT_STS_MSK_REG1),
446 	RK816_IRQ_MSK_OFFSET(RK816_INT_STS_MSK_REG2),
447 	RK816_IRQ_MSK_OFFSET(RK816_INT_STS_MSK_REG3),
448 };
449 
450 static unsigned int rk816_get_irq_reg(struct regmap_irq_chip_data *data,
451 				      unsigned int base, int index)
452 {
453 	unsigned int irq_reg = base;
454 
455 	switch (base) {
456 	case RK816_INT_STS_REG1:
457 		irq_reg += rk816_irq_status_offsets[index];
458 		break;
459 	case RK816_INT_STS_MSK_REG1:
460 		irq_reg += rk816_irq_mask_offsets[index];
461 		break;
462 	}
463 
464 	return irq_reg;
465 };
466 
467 static const struct regmap_irq rk816_irqs[] = {
468 	/* INT_STS_REG1 IRQs */
469 	REGMAP_IRQ_REG(RK816_IRQ_PWRON_FALL, 0, RK816_INT_STS_PWRON_FALL),
470 	REGMAP_IRQ_REG(RK816_IRQ_PWRON_RISE, 0, RK816_INT_STS_PWRON_RISE),
471 
472 	/* INT_STS_REG2 IRQs  */
473 	REGMAP_IRQ_REG(RK816_IRQ_VB_LOW, 1, RK816_INT_STS_VB_LOW),
474 	REGMAP_IRQ_REG(RK816_IRQ_PWRON, 1, RK816_INT_STS_PWRON),
475 	REGMAP_IRQ_REG(RK816_IRQ_PWRON_LP, 1, RK816_INT_STS_PWRON_LP),
476 	REGMAP_IRQ_REG(RK816_IRQ_HOTDIE, 1, RK816_INT_STS_HOTDIE),
477 	REGMAP_IRQ_REG(RK816_IRQ_RTC_ALARM, 1, RK816_INT_STS_RTC_ALARM),
478 	REGMAP_IRQ_REG(RK816_IRQ_RTC_PERIOD, 1, RK816_INT_STS_RTC_PERIOD),
479 	REGMAP_IRQ_REG(RK816_IRQ_USB_OV, 1, RK816_INT_STS_USB_OV),
480 
481 	/* INT_STS3 IRQs */
482 	REGMAP_IRQ_REG(RK816_IRQ_PLUG_IN, 2, RK816_INT_STS_PLUG_IN),
483 	REGMAP_IRQ_REG(RK816_IRQ_PLUG_OUT, 2, RK816_INT_STS_PLUG_OUT),
484 	REGMAP_IRQ_REG(RK816_IRQ_CHG_OK, 2, RK816_INT_STS_CHG_OK),
485 	REGMAP_IRQ_REG(RK816_IRQ_CHG_TE, 2, RK816_INT_STS_CHG_TE),
486 	REGMAP_IRQ_REG(RK816_IRQ_CHG_TS, 2, RK816_INT_STS_CHG_TS),
487 	REGMAP_IRQ_REG(RK816_IRQ_CHG_CVTLIM, 2, RK816_INT_STS_CHG_CVTLIM),
488 	REGMAP_IRQ_REG(RK816_IRQ_DISCHG_ILIM, 2, RK816_INT_STS_DISCHG_ILIM),
489 };
490 
491 static const struct regmap_irq rk818_irqs[] = {
492 	/* INT_STS */
493 	[RK818_IRQ_VOUT_LO] = {
494 		.mask = RK818_IRQ_VOUT_LO_MSK,
495 		.reg_offset = 0,
496 	},
497 	[RK818_IRQ_VB_LO] = {
498 		.mask = RK818_IRQ_VB_LO_MSK,
499 		.reg_offset = 0,
500 	},
501 	[RK818_IRQ_PWRON] = {
502 		.mask = RK818_IRQ_PWRON_MSK,
503 		.reg_offset = 0,
504 	},
505 	[RK818_IRQ_PWRON_LP] = {
506 		.mask = RK818_IRQ_PWRON_LP_MSK,
507 		.reg_offset = 0,
508 	},
509 	[RK818_IRQ_HOTDIE] = {
510 		.mask = RK818_IRQ_HOTDIE_MSK,
511 		.reg_offset = 0,
512 	},
513 	[RK818_IRQ_RTC_ALARM] = {
514 		.mask = RK818_IRQ_RTC_ALARM_MSK,
515 		.reg_offset = 0,
516 	},
517 	[RK818_IRQ_RTC_PERIOD] = {
518 		.mask = RK818_IRQ_RTC_PERIOD_MSK,
519 		.reg_offset = 0,
520 	},
521 	[RK818_IRQ_USB_OV] = {
522 		.mask = RK818_IRQ_USB_OV_MSK,
523 		.reg_offset = 0,
524 	},
525 
526 	/* INT_STS2 */
527 	[RK818_IRQ_PLUG_IN] = {
528 		.mask = RK818_IRQ_PLUG_IN_MSK,
529 		.reg_offset = 1,
530 	},
531 	[RK818_IRQ_PLUG_OUT] = {
532 		.mask = RK818_IRQ_PLUG_OUT_MSK,
533 		.reg_offset = 1,
534 	},
535 	[RK818_IRQ_CHG_OK] = {
536 		.mask = RK818_IRQ_CHG_OK_MSK,
537 		.reg_offset = 1,
538 	},
539 	[RK818_IRQ_CHG_TE] = {
540 		.mask = RK818_IRQ_CHG_TE_MSK,
541 		.reg_offset = 1,
542 	},
543 	[RK818_IRQ_CHG_TS1] = {
544 		.mask = RK818_IRQ_CHG_TS1_MSK,
545 		.reg_offset = 1,
546 	},
547 	[RK818_IRQ_TS2] = {
548 		.mask = RK818_IRQ_TS2_MSK,
549 		.reg_offset = 1,
550 	},
551 	[RK818_IRQ_CHG_CVTLIM] = {
552 		.mask = RK818_IRQ_CHG_CVTLIM_MSK,
553 		.reg_offset = 1,
554 	},
555 	[RK818_IRQ_DISCHG_ILIM] = {
556 		.mask = RK818_IRQ_DISCHG_ILIM_MSK,
557 		.reg_offset = 1,
558 	},
559 };
560 
561 static const struct regmap_irq rk817_irqs[RK817_IRQ_END] = {
562 	REGMAP_IRQ_REG_LINE(0, 8),
563 	REGMAP_IRQ_REG_LINE(1, 8),
564 	REGMAP_IRQ_REG_LINE(2, 8),
565 	REGMAP_IRQ_REG_LINE(3, 8),
566 	REGMAP_IRQ_REG_LINE(4, 8),
567 	REGMAP_IRQ_REG_LINE(5, 8),
568 	REGMAP_IRQ_REG_LINE(6, 8),
569 	REGMAP_IRQ_REG_LINE(7, 8),
570 	REGMAP_IRQ_REG_LINE(8, 8),
571 	REGMAP_IRQ_REG_LINE(9, 8),
572 	REGMAP_IRQ_REG_LINE(10, 8),
573 	REGMAP_IRQ_REG_LINE(11, 8),
574 	REGMAP_IRQ_REG_LINE(12, 8),
575 	REGMAP_IRQ_REG_LINE(13, 8),
576 	REGMAP_IRQ_REG_LINE(14, 8),
577 	REGMAP_IRQ_REG_LINE(15, 8),
578 	REGMAP_IRQ_REG_LINE(16, 8),
579 	REGMAP_IRQ_REG_LINE(17, 8),
580 	REGMAP_IRQ_REG_LINE(18, 8),
581 	REGMAP_IRQ_REG_LINE(19, 8),
582 	REGMAP_IRQ_REG_LINE(20, 8),
583 	REGMAP_IRQ_REG_LINE(21, 8),
584 	REGMAP_IRQ_REG_LINE(22, 8),
585 	REGMAP_IRQ_REG_LINE(23, 8)
586 };
587 
588 static const struct regmap_irq_chip rk801_irq_chip = {
589 	.name = "rk801",
590 	.irqs = rk801_irqs,
591 	.num_irqs = ARRAY_SIZE(rk801_irqs),
592 	.num_regs = 1,
593 	.status_base = RK801_INT_STS0_REG,
594 	.mask_base = RK801_INT_MASK0_REG,
595 	.ack_base = RK801_INT_STS0_REG,
596 	.init_ack_masked = true,
597 };
598 
599 static const struct regmap_irq_chip rk805_irq_chip = {
600 	.name = "rk805",
601 	.irqs = rk805_irqs,
602 	.num_irqs = ARRAY_SIZE(rk805_irqs),
603 	.num_regs = 1,
604 	.status_base = RK805_INT_STS_REG,
605 	.mask_base = RK805_INT_STS_MSK_REG,
606 	.ack_base = RK805_INT_STS_REG,
607 	.init_ack_masked = true,
608 };
609 
610 static const struct regmap_irq_chip rk806_irq_chip = {
611 	.name = "rk806",
612 	.irqs = rk806_irqs,
613 	.num_irqs = ARRAY_SIZE(rk806_irqs),
614 	.num_regs = 2,
615 	.irq_reg_stride = 2,
616 	.mask_base = RK806_INT_MSK0,
617 	.status_base = RK806_INT_STS0,
618 	.ack_base = RK806_INT_STS0,
619 	.init_ack_masked = true,
620 };
621 
622 static const struct regmap_irq_chip rk808_irq_chip = {
623 	.name = "rk808",
624 	.irqs = rk808_irqs,
625 	.num_irqs = ARRAY_SIZE(rk808_irqs),
626 	.num_regs = 2,
627 	.irq_reg_stride = 2,
628 	.status_base = RK808_INT_STS_REG1,
629 	.mask_base = RK808_INT_STS_MSK_REG1,
630 	.ack_base = RK808_INT_STS_REG1,
631 	.init_ack_masked = true,
632 };
633 
634 static const struct regmap_irq_chip rk816_irq_chip = {
635 	.name = "rk816",
636 	.irqs = rk816_irqs,
637 	.num_irqs = ARRAY_SIZE(rk816_irqs),
638 	.num_regs = 3,
639 	.get_irq_reg = rk816_get_irq_reg,
640 	.status_base = RK816_INT_STS_REG1,
641 	.mask_base = RK816_INT_STS_MSK_REG1,
642 	.ack_base = RK816_INT_STS_REG1,
643 	.init_ack_masked = true,
644 };
645 
646 static const struct regmap_irq_chip rk817_irq_chip = {
647 	.name = "rk817",
648 	.irqs = rk817_irqs,
649 	.num_irqs = ARRAY_SIZE(rk817_irqs),
650 	.num_regs = 3,
651 	.irq_reg_stride = 2,
652 	.status_base = RK817_INT_STS_REG0,
653 	.mask_base = RK817_INT_STS_MSK_REG0,
654 	.ack_base = RK817_INT_STS_REG0,
655 	.init_ack_masked = true,
656 };
657 
658 static const struct regmap_irq_chip rk818_irq_chip = {
659 	.name = "rk818",
660 	.irqs = rk818_irqs,
661 	.num_irqs = ARRAY_SIZE(rk818_irqs),
662 	.num_regs = 2,
663 	.irq_reg_stride = 2,
664 	.status_base = RK818_INT_STS_REG1,
665 	.mask_base = RK818_INT_STS_MSK_REG1,
666 	.ack_base = RK818_INT_STS_REG1,
667 	.init_ack_masked = true,
668 };
669 
670 static int rk808_power_off(struct sys_off_data *data)
671 {
672 	struct rk808 *rk808 = data->cb_data;
673 	int ret;
674 	unsigned int reg, bit;
675 
676 	switch (rk808->variant) {
677 	case RK801_ID:
678 		reg = RK801_SYS_CFG2_REG;
679 		bit = DEV_OFF;
680 		break;
681 	case RK805_ID:
682 		reg = RK805_DEV_CTRL_REG;
683 		bit = DEV_OFF;
684 		break;
685 	case RK806_ID:
686 		reg = RK806_SYS_CFG3;
687 		bit = DEV_OFF;
688 		break;
689 	case RK808_ID:
690 		reg = RK808_DEVCTRL_REG;
691 		bit = DEV_OFF_RST;
692 		break;
693 	case RK809_ID:
694 	case RK817_ID:
695 		reg = RK817_SYS_CFG(3);
696 		bit = DEV_OFF;
697 		break;
698 	case RK816_ID:
699 	case RK818_ID:
700 		reg = RK818_DEVCTRL_REG;
701 		bit = DEV_OFF;
702 		break;
703 	default:
704 		return NOTIFY_DONE;
705 	}
706 	ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
707 	if (ret)
708 		dev_err(rk808->dev, "Failed to shutdown device!\n");
709 
710 	return NOTIFY_DONE;
711 }
712 
713 static int rk808_restart(struct sys_off_data *data)
714 {
715 	struct rk808 *rk808 = data->cb_data;
716 	unsigned int reg, bit;
717 	int ret;
718 
719 	switch (rk808->variant) {
720 	case RK809_ID:
721 	case RK817_ID:
722 		reg = RK817_SYS_CFG(3);
723 		bit = DEV_RST;
724 		break;
725 
726 	default:
727 		return NOTIFY_DONE;
728 	}
729 	ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
730 	if (ret)
731 		dev_err(rk808->dev, "Failed to restart device!\n");
732 
733 	return NOTIFY_DONE;
734 }
735 
736 void rk8xx_shutdown(struct device *dev)
737 {
738 	struct rk808 *rk808 = dev_get_drvdata(dev);
739 	int ret;
740 
741 	switch (rk808->variant) {
742 	case RK805_ID:
743 		ret = regmap_update_bits(rk808->regmap,
744 					 RK805_GPIO_IO_POL_REG,
745 					 SLP_SD_MSK,
746 					 SHUTDOWN_FUN);
747 		break;
748 	case RK809_ID:
749 	case RK817_ID:
750 		ret = regmap_update_bits(rk808->regmap,
751 					 RK817_SYS_CFG(3),
752 					 RK817_SLPPIN_FUNC_MSK,
753 					 SLPPIN_DN_FUN);
754 		break;
755 	default:
756 		return;
757 	}
758 	if (ret)
759 		dev_warn(dev,
760 			 "Cannot switch to power down function\n");
761 }
762 EXPORT_SYMBOL_GPL(rk8xx_shutdown);
763 
764 int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap)
765 {
766 	struct rk808 *rk808;
767 	const struct rk808_reg_data *pre_init_reg;
768 	const struct mfd_cell *cells;
769 	int dual_support = 0;
770 	int nr_pre_init_regs;
771 	u32 rst_fun = 0;
772 	int nr_cells;
773 	int ret;
774 	int i;
775 
776 	rk808 = devm_kzalloc(dev, sizeof(*rk808), GFP_KERNEL);
777 	if (!rk808)
778 		return -ENOMEM;
779 	rk808->dev = dev;
780 	rk808->variant = variant;
781 	rk808->regmap = regmap;
782 	dev_set_drvdata(dev, rk808);
783 
784 	switch (rk808->variant) {
785 	case RK801_ID:
786 		rk808->regmap_irq_chip = &rk801_irq_chip;
787 		pre_init_reg = rk801_pre_init_reg;
788 		nr_pre_init_regs = ARRAY_SIZE(rk801_pre_init_reg);
789 		cells = rk801s;
790 		nr_cells = ARRAY_SIZE(rk801s);
791 		break;
792 	case RK805_ID:
793 		rk808->regmap_irq_chip = &rk805_irq_chip;
794 		pre_init_reg = rk805_pre_init_reg;
795 		nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg);
796 		cells = rk805s;
797 		nr_cells = ARRAY_SIZE(rk805s);
798 		break;
799 	case RK806_ID:
800 		rk808->regmap_irq_chip = &rk806_irq_chip;
801 		pre_init_reg = rk806_pre_init_reg;
802 		nr_pre_init_regs = ARRAY_SIZE(rk806_pre_init_reg);
803 		cells = rk806s;
804 		nr_cells = ARRAY_SIZE(rk806s);
805 		dual_support = IRQF_SHARED;
806 
807 		ret = device_property_read_u32(dev, "rockchip,reset-mode", &rst_fun);
808 		if (ret)
809 			break;
810 
811 		ret = regmap_update_bits(rk808->regmap, RK806_SYS_CFG3, RK806_RST_FUN_MSK,
812 					 FIELD_PREP(RK806_RST_FUN_MSK, rst_fun));
813 		if (ret)
814 			return dev_err_probe(dev, ret,
815 					     "Failed to configure requested restart/reset behavior\n");
816 		break;
817 	case RK808_ID:
818 		rk808->regmap_irq_chip = &rk808_irq_chip;
819 		pre_init_reg = rk808_pre_init_reg;
820 		nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg);
821 		cells = rk808s;
822 		nr_cells = ARRAY_SIZE(rk808s);
823 		break;
824 	case RK816_ID:
825 		rk808->regmap_irq_chip = &rk816_irq_chip;
826 		pre_init_reg = rk816_pre_init_reg;
827 		nr_pre_init_regs = ARRAY_SIZE(rk816_pre_init_reg);
828 		cells = rk816s;
829 		nr_cells = ARRAY_SIZE(rk816s);
830 		break;
831 	case RK818_ID:
832 		rk808->regmap_irq_chip = &rk818_irq_chip;
833 		pre_init_reg = rk818_pre_init_reg;
834 		nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg);
835 		cells = rk818s;
836 		nr_cells = ARRAY_SIZE(rk818s);
837 		break;
838 	case RK809_ID:
839 	case RK817_ID:
840 		rk808->regmap_irq_chip = &rk817_irq_chip;
841 		pre_init_reg = rk817_pre_init_reg;
842 		nr_pre_init_regs = ARRAY_SIZE(rk817_pre_init_reg);
843 		cells = rk817s;
844 		nr_cells = ARRAY_SIZE(rk817s);
845 		break;
846 	default:
847 		dev_err(dev, "Unsupported RK8XX ID %lu\n", rk808->variant);
848 		return -EINVAL;
849 	}
850 
851 	if (!irq)
852 		return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n");
853 
854 	ret = devm_regmap_add_irq_chip(dev, rk808->regmap, irq,
855 				       IRQF_ONESHOT | dual_support, -1,
856 				       rk808->regmap_irq_chip, &rk808->irq_data);
857 	if (ret)
858 		return dev_err_probe(dev, ret, "Failed to add irq_chip\n");
859 
860 	for (i = 0; i < nr_pre_init_regs; i++) {
861 		ret = regmap_update_bits(rk808->regmap,
862 					pre_init_reg[i].addr,
863 					pre_init_reg[i].mask,
864 					pre_init_reg[i].value);
865 		if (ret)
866 			return dev_err_probe(dev, ret, "0x%x write err\n",
867 					     pre_init_reg[i].addr);
868 	}
869 
870 	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, cells, nr_cells, NULL, 0,
871 			      regmap_irq_get_domain(rk808->irq_data));
872 	if (ret)
873 		return dev_err_probe(dev, ret, "failed to add MFD devices\n");
874 
875 	if (device_property_read_bool(dev, "system-power-controller") ||
876 	    device_property_read_bool(dev, "rockchip,system-power-controller")) {
877 		ret = devm_register_sys_off_handler(dev,
878 				    SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH,
879 				    &rk808_power_off, rk808);
880 		if (ret)
881 			return dev_err_probe(dev, ret,
882 					     "failed to register poweroff handler\n");
883 
884 		switch (rk808->variant) {
885 		case RK809_ID:
886 		case RK817_ID:
887 			ret = devm_register_sys_off_handler(dev,
888 							    SYS_OFF_MODE_RESTART, SYS_OFF_PRIO_HIGH,
889 							    &rk808_restart, rk808);
890 			if (ret)
891 				dev_warn(dev, "failed to register rst handler, %d\n", ret);
892 			break;
893 		default:
894 			dev_dbg(dev, "pmic controlled board reset not supported\n");
895 			break;
896 		}
897 	}
898 
899 	return 0;
900 }
901 EXPORT_SYMBOL_GPL(rk8xx_probe);
902 
903 int rk8xx_suspend(struct device *dev)
904 {
905 	struct rk808 *rk808 = dev_get_drvdata(dev);
906 	int ret = 0;
907 
908 	switch (rk808->variant) {
909 	case RK801_ID:
910 		ret = regmap_update_bits(rk808->regmap,
911 					 RK801_SLEEP_CFG_REG,
912 					 RK801_SLEEP_FUN_MSK,
913 					 RK801_SLEEP_FUN);
914 		break;
915 	case RK805_ID:
916 		ret = regmap_update_bits(rk808->regmap,
917 					 RK805_GPIO_IO_POL_REG,
918 					 SLP_SD_MSK,
919 					 SLEEP_FUN);
920 		break;
921 	case RK809_ID:
922 	case RK817_ID:
923 		ret = regmap_update_bits(rk808->regmap,
924 					 RK817_SYS_CFG(3),
925 					 RK817_SLPPIN_FUNC_MSK,
926 					 SLPPIN_SLP_FUN);
927 		break;
928 	default:
929 		break;
930 	}
931 
932 	return ret;
933 }
934 EXPORT_SYMBOL_GPL(rk8xx_suspend);
935 
936 int rk8xx_resume(struct device *dev)
937 {
938 	struct rk808 *rk808 = dev_get_drvdata(dev);
939 	int ret = 0;
940 
941 	switch (rk808->variant) {
942 	case RK809_ID:
943 	case RK817_ID:
944 		ret = regmap_update_bits(rk808->regmap,
945 					 RK817_SYS_CFG(3),
946 					 RK817_SLPPIN_FUNC_MSK,
947 					 SLPPIN_NULL_FUN);
948 		break;
949 	default:
950 		break;
951 	}
952 
953 	return ret;
954 }
955 EXPORT_SYMBOL_GPL(rk8xx_resume);
956 
957 MODULE_LICENSE("GPL");
958 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
959 MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
960 MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
961 MODULE_DESCRIPTION("RK8xx PMIC core");
962