GNU Linux-libre 6.8.7-gnu
[releases.git] / drivers / mfd / rk8xx-core.c
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/interrupt.h>
14 #include <linux/mfd/rk808.h>
15 #include <linux/mfd/core.h>
16 #include <linux/module.h>
17 #include <linux/property.h>
18 #include <linux/regmap.h>
19 #include <linux/reboot.h>
20
21 struct rk808_reg_data {
22         int addr;
23         int mask;
24         int value;
25 };
26
27 static const struct resource rtc_resources[] = {
28         DEFINE_RES_IRQ(RK808_IRQ_RTC_ALARM),
29 };
30
31 static const struct resource rk817_rtc_resources[] = {
32         DEFINE_RES_IRQ(RK817_IRQ_RTC_ALARM),
33 };
34
35 static const struct resource rk805_key_resources[] = {
36         DEFINE_RES_IRQ(RK805_IRQ_PWRON_RISE),
37         DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL),
38 };
39
40 static struct resource rk806_pwrkey_resources[] = {
41         DEFINE_RES_IRQ(RK806_IRQ_PWRON_FALL),
42         DEFINE_RES_IRQ(RK806_IRQ_PWRON_RISE),
43 };
44
45 static const struct resource rk817_pwrkey_resources[] = {
46         DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE),
47         DEFINE_RES_IRQ(RK817_IRQ_PWRON_FALL),
48 };
49
50 static const struct resource rk817_charger_resources[] = {
51         DEFINE_RES_IRQ(RK817_IRQ_PLUG_IN),
52         DEFINE_RES_IRQ(RK817_IRQ_PLUG_OUT),
53 };
54
55 static const struct mfd_cell rk805s[] = {
56         { .name = "rk808-clkout", },
57         { .name = "rk808-regulator", },
58         { .name = "rk805-pinctrl", },
59         {
60                 .name = "rk808-rtc",
61                 .num_resources = ARRAY_SIZE(rtc_resources),
62                 .resources = &rtc_resources[0],
63         },
64         {       .name = "rk805-pwrkey",
65                 .num_resources = ARRAY_SIZE(rk805_key_resources),
66                 .resources = &rk805_key_resources[0],
67         },
68 };
69
70 static const struct mfd_cell rk806s[] = {
71         { .name = "rk805-pinctrl", },
72         { .name = "rk808-regulator", },
73         {
74                 .name = "rk805-pwrkey",
75                 .resources = rk806_pwrkey_resources,
76                 .num_resources = ARRAY_SIZE(rk806_pwrkey_resources),
77         },
78 };
79
80 static const struct mfd_cell rk808s[] = {
81         { .name = "rk808-clkout", },
82         { .name = "rk808-regulator", },
83         {
84                 .name = "rk808-rtc",
85                 .num_resources = ARRAY_SIZE(rtc_resources),
86                 .resources = rtc_resources,
87         },
88 };
89
90 static const struct mfd_cell rk817s[] = {
91         { .name = "rk808-clkout", },
92         { .name = "rk808-regulator", },
93         {
94                 .name = "rk805-pwrkey",
95                 .num_resources = ARRAY_SIZE(rk817_pwrkey_resources),
96                 .resources = &rk817_pwrkey_resources[0],
97         },
98         {
99                 .name = "rk808-rtc",
100                 .num_resources = ARRAY_SIZE(rk817_rtc_resources),
101                 .resources = &rk817_rtc_resources[0],
102         },
103         { .name = "rk817-codec", },
104         {
105                 .name = "rk817-charger",
106                 .num_resources = ARRAY_SIZE(rk817_charger_resources),
107                 .resources = &rk817_charger_resources[0],
108         },
109 };
110
111 static const struct mfd_cell rk818s[] = {
112         { .name = "rk808-clkout", },
113         { .name = "rk808-regulator", },
114         {
115                 .name = "rk808-rtc",
116                 .num_resources = ARRAY_SIZE(rtc_resources),
117                 .resources = rtc_resources,
118         },
119 };
120
121 static const struct rk808_reg_data rk805_pre_init_reg[] = {
122         {RK805_BUCK1_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
123                                  RK805_BUCK1_2_ILMAX_4000MA},
124         {RK805_BUCK2_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
125                                  RK805_BUCK1_2_ILMAX_4000MA},
126         {RK805_BUCK3_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK,
127                                  RK805_BUCK3_ILMAX_3000MA},
128         {RK805_BUCK4_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK,
129                                  RK805_BUCK4_ILMAX_3500MA},
130         {RK805_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_400MA},
131         {RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C},
132 };
133
134 static const struct rk808_reg_data rk806_pre_init_reg[] = {
135         { RK806_GPIO_INT_CONFIG, RK806_INT_POL_MSK, RK806_INT_POL_L },
136         { RK806_SYS_CFG3, RK806_SLAVE_RESTART_FUN_MSK, RK806_SLAVE_RESTART_FUN_EN },
137         { RK806_SYS_OPTION, RK806_SYS_ENB2_2M_MSK, RK806_SYS_ENB2_2M_EN },
138 };
139
140 static const struct rk808_reg_data rk808_pre_init_reg[] = {
141         { RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_150MA },
142         { RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_200MA },
143         { RK808_BOOST_CONFIG_REG, BOOST_ILMIN_MASK, BOOST_ILMIN_100MA },
144         { RK808_BUCK1_CONFIG_REG, BUCK1_RATE_MASK,  BUCK_ILMIN_200MA },
145         { RK808_BUCK2_CONFIG_REG, BUCK2_RATE_MASK,  BUCK_ILMIN_200MA },
146         { RK808_DCDC_UV_ACT_REG,  BUCK_UV_ACT_MASK, BUCK_UV_ACT_DISABLE},
147         { RK808_VB_MON_REG,       MASK_ALL,         VB_LO_ACT |
148                                                     VB_LO_SEL_3500MV },
149 };
150
151 static const struct rk808_reg_data rk817_pre_init_reg[] = {
152         {RK817_RTC_CTRL_REG, RTC_STOP, RTC_STOP},
153         /* Codec specific registers */
154         { RK817_CODEC_DTOP_VUCTL, MASK_ALL, 0x03 },
155         { RK817_CODEC_DTOP_VUCTIME, MASK_ALL, 0x00 },
156         { RK817_CODEC_DTOP_LPT_SRST, MASK_ALL, 0x00 },
157         { RK817_CODEC_DTOP_DIGEN_CLKE, MASK_ALL, 0x00 },
158         /* from vendor driver, CODEC_AREF_RTCFG0 not defined in data sheet */
159         { RK817_CODEC_AREF_RTCFG0, MASK_ALL, 0x00 },
160         { RK817_CODEC_AREF_RTCFG1, MASK_ALL, 0x06 },
161         { RK817_CODEC_AADC_CFG0, MASK_ALL, 0xc8 },
162         /* from vendor driver, CODEC_AADC_CFG1 not defined in data sheet */
163         { RK817_CODEC_AADC_CFG1, MASK_ALL, 0x00 },
164         { RK817_CODEC_DADC_VOLL, MASK_ALL, 0x00 },
165         { RK817_CODEC_DADC_VOLR, MASK_ALL, 0x00 },
166         { RK817_CODEC_DADC_SR_ACL0, MASK_ALL, 0x00 },
167         { RK817_CODEC_DADC_ALC1, MASK_ALL, 0x00 },
168         { RK817_CODEC_DADC_ALC2, MASK_ALL, 0x00 },
169         { RK817_CODEC_DADC_NG, MASK_ALL, 0x00 },
170         { RK817_CODEC_DADC_HPF, MASK_ALL, 0x00 },
171         { RK817_CODEC_DADC_RVOLL, MASK_ALL, 0xff },
172         { RK817_CODEC_DADC_RVOLR, MASK_ALL, 0xff },
173         { RK817_CODEC_AMIC_CFG0, MASK_ALL, 0x70 },
174         { RK817_CODEC_AMIC_CFG1, MASK_ALL, 0x00 },
175         { RK817_CODEC_DMIC_PGA_GAIN, MASK_ALL, 0x66 },
176         { RK817_CODEC_DMIC_LMT1, MASK_ALL, 0x00 },
177         { RK817_CODEC_DMIC_LMT2, MASK_ALL, 0x00 },
178         { RK817_CODEC_DMIC_NG1, MASK_ALL, 0x00 },
179         { RK817_CODEC_DMIC_NG2, MASK_ALL, 0x00 },
180         /* from vendor driver, CODEC_ADAC_CFG0 not defined in data sheet */
181         { RK817_CODEC_ADAC_CFG0, MASK_ALL, 0x00 },
182         { RK817_CODEC_ADAC_CFG1, MASK_ALL, 0x07 },
183         { RK817_CODEC_DDAC_POPD_DACST, MASK_ALL, 0x82 },
184         { RK817_CODEC_DDAC_VOLL, MASK_ALL, 0x00 },
185         { RK817_CODEC_DDAC_VOLR, MASK_ALL, 0x00 },
186         { RK817_CODEC_DDAC_SR_LMT0, MASK_ALL, 0x00 },
187         { RK817_CODEC_DDAC_LMT1, MASK_ALL, 0x00 },
188         { RK817_CODEC_DDAC_LMT2, MASK_ALL, 0x00 },
189         { RK817_CODEC_DDAC_MUTE_MIXCTL, MASK_ALL, 0xa0 },
190         { RK817_CODEC_DDAC_RVOLL, MASK_ALL, 0xff },
191         { RK817_CODEC_DADC_RVOLR, MASK_ALL, 0xff },
192         { RK817_CODEC_AMIC_CFG0, MASK_ALL, 0x70 },
193         { RK817_CODEC_AMIC_CFG1, MASK_ALL, 0x00 },
194         { RK817_CODEC_DMIC_PGA_GAIN, MASK_ALL, 0x66 },
195         { RK817_CODEC_DMIC_LMT1, MASK_ALL, 0x00 },
196         { RK817_CODEC_DMIC_LMT2, MASK_ALL, 0x00 },
197         { RK817_CODEC_DMIC_NG1, MASK_ALL, 0x00 },
198         { RK817_CODEC_DMIC_NG2, MASK_ALL, 0x00 },
199         /* from vendor driver, CODEC_ADAC_CFG0 not defined in data sheet */
200         { RK817_CODEC_ADAC_CFG0, MASK_ALL, 0x00 },
201         { RK817_CODEC_ADAC_CFG1, MASK_ALL, 0x07 },
202         { RK817_CODEC_DDAC_POPD_DACST, MASK_ALL, 0x82 },
203         { RK817_CODEC_DDAC_VOLL, MASK_ALL, 0x00 },
204         { RK817_CODEC_DDAC_VOLR, MASK_ALL, 0x00 },
205         { RK817_CODEC_DDAC_SR_LMT0, MASK_ALL, 0x00 },
206         { RK817_CODEC_DDAC_LMT1, MASK_ALL, 0x00 },
207         { RK817_CODEC_DDAC_LMT2, MASK_ALL, 0x00 },
208         { RK817_CODEC_DDAC_MUTE_MIXCTL, MASK_ALL, 0xa0 },
209         { RK817_CODEC_DDAC_RVOLL, MASK_ALL, 0xff },
210         { RK817_CODEC_DDAC_RVOLR, MASK_ALL, 0xff },
211         { RK817_CODEC_AHP_ANTI0, MASK_ALL, 0x00 },
212         { RK817_CODEC_AHP_ANTI1, MASK_ALL, 0x00 },
213         { RK817_CODEC_AHP_CFG0, MASK_ALL, 0xe0 },
214         { RK817_CODEC_AHP_CFG1, MASK_ALL, 0x1f },
215         { RK817_CODEC_AHP_CP, MASK_ALL, 0x09 },
216         { RK817_CODEC_ACLASSD_CFG1, MASK_ALL, 0x69 },
217         { RK817_CODEC_ACLASSD_CFG2, MASK_ALL, 0x44 },
218         { RK817_CODEC_APLL_CFG0, MASK_ALL, 0x04 },
219         { RK817_CODEC_APLL_CFG1, MASK_ALL, 0x00 },
220         { RK817_CODEC_APLL_CFG2, MASK_ALL, 0x30 },
221         { RK817_CODEC_APLL_CFG3, MASK_ALL, 0x19 },
222         { RK817_CODEC_APLL_CFG4, MASK_ALL, 0x65 },
223         { RK817_CODEC_APLL_CFG5, MASK_ALL, 0x01 },
224         { RK817_CODEC_DI2S_CKM, MASK_ALL, 0x01 },
225         { RK817_CODEC_DI2S_RSD, MASK_ALL, 0x00 },
226         { RK817_CODEC_DI2S_RXCR1, MASK_ALL, 0x00 },
227         { RK817_CODEC_DI2S_RXCR2, MASK_ALL, 0x17 },
228         { RK817_CODEC_DI2S_RXCMD_TSD, MASK_ALL, 0x00 },
229         { RK817_CODEC_DI2S_TXCR1, MASK_ALL, 0x00 },
230         { RK817_CODEC_DI2S_TXCR2, MASK_ALL, 0x17 },
231         { RK817_CODEC_DI2S_TXCR3_TXCMD, MASK_ALL, 0x00 },
232         {RK817_GPIO_INT_CFG, RK817_INT_POL_MSK, RK817_INT_POL_L},
233         {RK817_SYS_CFG(1), RK817_HOTDIE_TEMP_MSK | RK817_TSD_TEMP_MSK,
234                                            RK817_HOTDIE_105 | RK817_TSD_140},
235 };
236
237 static const struct rk808_reg_data rk818_pre_init_reg[] = {
238         /* improve efficiency */
239         { RK818_BUCK2_CONFIG_REG, BUCK2_RATE_MASK,  BUCK_ILMIN_250MA },
240         { RK818_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_250MA },
241         { RK818_BOOST_CONFIG_REG, BOOST_ILMIN_MASK, BOOST_ILMIN_100MA },
242         { RK818_USB_CTRL_REG,     RK818_USB_ILIM_SEL_MASK,
243                                                     RK818_USB_ILMIN_2000MA },
244         /* close charger when usb lower then 3.4V */
245         { RK818_USB_CTRL_REG,     RK818_USB_CHG_SD_VSEL_MASK,
246                                                     (0x7 << 4) },
247         /* no action when vref */
248         { RK818_H5V_EN_REG,       BIT(1),           RK818_REF_RDY_CTRL },
249         /* enable HDMI 5V */
250         { RK818_H5V_EN_REG,       BIT(0),           RK818_H5V_EN },
251         { RK808_VB_MON_REG,       MASK_ALL,         VB_LO_ACT |
252                                                     VB_LO_SEL_3500MV },
253 };
254
255 static const struct regmap_irq rk805_irqs[] = {
256         [RK805_IRQ_PWRON_RISE] = {
257                 .mask = RK805_IRQ_PWRON_RISE_MSK,
258                 .reg_offset = 0,
259         },
260         [RK805_IRQ_VB_LOW] = {
261                 .mask = RK805_IRQ_VB_LOW_MSK,
262                 .reg_offset = 0,
263         },
264         [RK805_IRQ_PWRON] = {
265                 .mask = RK805_IRQ_PWRON_MSK,
266                 .reg_offset = 0,
267         },
268         [RK805_IRQ_PWRON_LP] = {
269                 .mask = RK805_IRQ_PWRON_LP_MSK,
270                 .reg_offset = 0,
271         },
272         [RK805_IRQ_HOTDIE] = {
273                 .mask = RK805_IRQ_HOTDIE_MSK,
274                 .reg_offset = 0,
275         },
276         [RK805_IRQ_RTC_ALARM] = {
277                 .mask = RK805_IRQ_RTC_ALARM_MSK,
278                 .reg_offset = 0,
279         },
280         [RK805_IRQ_RTC_PERIOD] = {
281                 .mask = RK805_IRQ_RTC_PERIOD_MSK,
282                 .reg_offset = 0,
283         },
284         [RK805_IRQ_PWRON_FALL] = {
285                 .mask = RK805_IRQ_PWRON_FALL_MSK,
286                 .reg_offset = 0,
287         },
288 };
289
290 static const struct regmap_irq rk806_irqs[] = {
291         /* INT_STS0 IRQs */
292         REGMAP_IRQ_REG(RK806_IRQ_PWRON_FALL, 0, RK806_INT_STS_PWRON_FALL),
293         REGMAP_IRQ_REG(RK806_IRQ_PWRON_RISE, 0, RK806_INT_STS_PWRON_RISE),
294         REGMAP_IRQ_REG(RK806_IRQ_PWRON, 0, RK806_INT_STS_PWRON),
295         REGMAP_IRQ_REG(RK806_IRQ_PWRON_LP, 0, RK806_INT_STS_PWRON_LP),
296         REGMAP_IRQ_REG(RK806_IRQ_HOTDIE, 0, RK806_INT_STS_HOTDIE),
297         REGMAP_IRQ_REG(RK806_IRQ_VDC_RISE, 0, RK806_INT_STS_VDC_RISE),
298         REGMAP_IRQ_REG(RK806_IRQ_VDC_FALL, 0, RK806_INT_STS_VDC_FALL),
299         REGMAP_IRQ_REG(RK806_IRQ_VB_LO, 0, RK806_INT_STS_VB_LO),
300         /* INT_STS1 IRQs */
301         REGMAP_IRQ_REG(RK806_IRQ_REV0, 1, RK806_INT_STS_REV0),
302         REGMAP_IRQ_REG(RK806_IRQ_REV1, 1, RK806_INT_STS_REV1),
303         REGMAP_IRQ_REG(RK806_IRQ_REV2, 1, RK806_INT_STS_REV2),
304         REGMAP_IRQ_REG(RK806_IRQ_CRC_ERROR, 1, RK806_INT_STS_CRC_ERROR),
305         REGMAP_IRQ_REG(RK806_IRQ_SLP3_GPIO, 1, RK806_INT_STS_SLP3_GPIO),
306         REGMAP_IRQ_REG(RK806_IRQ_SLP2_GPIO, 1, RK806_INT_STS_SLP2_GPIO),
307         REGMAP_IRQ_REG(RK806_IRQ_SLP1_GPIO, 1, RK806_INT_STS_SLP1_GPIO),
308         REGMAP_IRQ_REG(RK806_IRQ_WDT, 1, RK806_INT_STS_WDT),
309 };
310
311 static const struct regmap_irq rk808_irqs[] = {
312         /* INT_STS */
313         [RK808_IRQ_VOUT_LO] = {
314                 .mask = RK808_IRQ_VOUT_LO_MSK,
315                 .reg_offset = 0,
316         },
317         [RK808_IRQ_VB_LO] = {
318                 .mask = RK808_IRQ_VB_LO_MSK,
319                 .reg_offset = 0,
320         },
321         [RK808_IRQ_PWRON] = {
322                 .mask = RK808_IRQ_PWRON_MSK,
323                 .reg_offset = 0,
324         },
325         [RK808_IRQ_PWRON_LP] = {
326                 .mask = RK808_IRQ_PWRON_LP_MSK,
327                 .reg_offset = 0,
328         },
329         [RK808_IRQ_HOTDIE] = {
330                 .mask = RK808_IRQ_HOTDIE_MSK,
331                 .reg_offset = 0,
332         },
333         [RK808_IRQ_RTC_ALARM] = {
334                 .mask = RK808_IRQ_RTC_ALARM_MSK,
335                 .reg_offset = 0,
336         },
337         [RK808_IRQ_RTC_PERIOD] = {
338                 .mask = RK808_IRQ_RTC_PERIOD_MSK,
339                 .reg_offset = 0,
340         },
341
342         /* INT_STS2 */
343         [RK808_IRQ_PLUG_IN_INT] = {
344                 .mask = RK808_IRQ_PLUG_IN_INT_MSK,
345                 .reg_offset = 1,
346         },
347         [RK808_IRQ_PLUG_OUT_INT] = {
348                 .mask = RK808_IRQ_PLUG_OUT_INT_MSK,
349                 .reg_offset = 1,
350         },
351 };
352
353 static const struct regmap_irq rk818_irqs[] = {
354         /* INT_STS */
355         [RK818_IRQ_VOUT_LO] = {
356                 .mask = RK818_IRQ_VOUT_LO_MSK,
357                 .reg_offset = 0,
358         },
359         [RK818_IRQ_VB_LO] = {
360                 .mask = RK818_IRQ_VB_LO_MSK,
361                 .reg_offset = 0,
362         },
363         [RK818_IRQ_PWRON] = {
364                 .mask = RK818_IRQ_PWRON_MSK,
365                 .reg_offset = 0,
366         },
367         [RK818_IRQ_PWRON_LP] = {
368                 .mask = RK818_IRQ_PWRON_LP_MSK,
369                 .reg_offset = 0,
370         },
371         [RK818_IRQ_HOTDIE] = {
372                 .mask = RK818_IRQ_HOTDIE_MSK,
373                 .reg_offset = 0,
374         },
375         [RK818_IRQ_RTC_ALARM] = {
376                 .mask = RK818_IRQ_RTC_ALARM_MSK,
377                 .reg_offset = 0,
378         },
379         [RK818_IRQ_RTC_PERIOD] = {
380                 .mask = RK818_IRQ_RTC_PERIOD_MSK,
381                 .reg_offset = 0,
382         },
383         [RK818_IRQ_USB_OV] = {
384                 .mask = RK818_IRQ_USB_OV_MSK,
385                 .reg_offset = 0,
386         },
387
388         /* INT_STS2 */
389         [RK818_IRQ_PLUG_IN] = {
390                 .mask = RK818_IRQ_PLUG_IN_MSK,
391                 .reg_offset = 1,
392         },
393         [RK818_IRQ_PLUG_OUT] = {
394                 .mask = RK818_IRQ_PLUG_OUT_MSK,
395                 .reg_offset = 1,
396         },
397         [RK818_IRQ_CHG_OK] = {
398                 .mask = RK818_IRQ_CHG_OK_MSK,
399                 .reg_offset = 1,
400         },
401         [RK818_IRQ_CHG_TE] = {
402                 .mask = RK818_IRQ_CHG_TE_MSK,
403                 .reg_offset = 1,
404         },
405         [RK818_IRQ_CHG_TS1] = {
406                 .mask = RK818_IRQ_CHG_TS1_MSK,
407                 .reg_offset = 1,
408         },
409         [RK818_IRQ_TS2] = {
410                 .mask = RK818_IRQ_TS2_MSK,
411                 .reg_offset = 1,
412         },
413         [RK818_IRQ_CHG_CVTLIM] = {
414                 .mask = RK818_IRQ_CHG_CVTLIM_MSK,
415                 .reg_offset = 1,
416         },
417         [RK818_IRQ_DISCHG_ILIM] = {
418                 .mask = RK818_IRQ_DISCHG_ILIM_MSK,
419                 .reg_offset = 1,
420         },
421 };
422
423 static const struct regmap_irq rk817_irqs[RK817_IRQ_END] = {
424         REGMAP_IRQ_REG_LINE(0, 8),
425         REGMAP_IRQ_REG_LINE(1, 8),
426         REGMAP_IRQ_REG_LINE(2, 8),
427         REGMAP_IRQ_REG_LINE(3, 8),
428         REGMAP_IRQ_REG_LINE(4, 8),
429         REGMAP_IRQ_REG_LINE(5, 8),
430         REGMAP_IRQ_REG_LINE(6, 8),
431         REGMAP_IRQ_REG_LINE(7, 8),
432         REGMAP_IRQ_REG_LINE(8, 8),
433         REGMAP_IRQ_REG_LINE(9, 8),
434         REGMAP_IRQ_REG_LINE(10, 8),
435         REGMAP_IRQ_REG_LINE(11, 8),
436         REGMAP_IRQ_REG_LINE(12, 8),
437         REGMAP_IRQ_REG_LINE(13, 8),
438         REGMAP_IRQ_REG_LINE(14, 8),
439         REGMAP_IRQ_REG_LINE(15, 8),
440         REGMAP_IRQ_REG_LINE(16, 8),
441         REGMAP_IRQ_REG_LINE(17, 8),
442         REGMAP_IRQ_REG_LINE(18, 8),
443         REGMAP_IRQ_REG_LINE(19, 8),
444         REGMAP_IRQ_REG_LINE(20, 8),
445         REGMAP_IRQ_REG_LINE(21, 8),
446         REGMAP_IRQ_REG_LINE(22, 8),
447         REGMAP_IRQ_REG_LINE(23, 8)
448 };
449
450 static struct regmap_irq_chip rk805_irq_chip = {
451         .name = "rk805",
452         .irqs = rk805_irqs,
453         .num_irqs = ARRAY_SIZE(rk805_irqs),
454         .num_regs = 1,
455         .status_base = RK805_INT_STS_REG,
456         .mask_base = RK805_INT_STS_MSK_REG,
457         .ack_base = RK805_INT_STS_REG,
458         .init_ack_masked = true,
459 };
460
461 static struct regmap_irq_chip rk806_irq_chip = {
462         .name = "rk806",
463         .irqs = rk806_irqs,
464         .num_irqs = ARRAY_SIZE(rk806_irqs),
465         .num_regs = 2,
466         .irq_reg_stride = 2,
467         .mask_base = RK806_INT_MSK0,
468         .status_base = RK806_INT_STS0,
469         .ack_base = RK806_INT_STS0,
470         .init_ack_masked = true,
471 };
472
473 static const struct regmap_irq_chip rk808_irq_chip = {
474         .name = "rk808",
475         .irqs = rk808_irqs,
476         .num_irqs = ARRAY_SIZE(rk808_irqs),
477         .num_regs = 2,
478         .irq_reg_stride = 2,
479         .status_base = RK808_INT_STS_REG1,
480         .mask_base = RK808_INT_STS_MSK_REG1,
481         .ack_base = RK808_INT_STS_REG1,
482         .init_ack_masked = true,
483 };
484
485 static struct regmap_irq_chip rk817_irq_chip = {
486         .name = "rk817",
487         .irqs = rk817_irqs,
488         .num_irqs = ARRAY_SIZE(rk817_irqs),
489         .num_regs = 3,
490         .irq_reg_stride = 2,
491         .status_base = RK817_INT_STS_REG0,
492         .mask_base = RK817_INT_STS_MSK_REG0,
493         .ack_base = RK817_INT_STS_REG0,
494         .init_ack_masked = true,
495 };
496
497 static const struct regmap_irq_chip rk818_irq_chip = {
498         .name = "rk818",
499         .irqs = rk818_irqs,
500         .num_irqs = ARRAY_SIZE(rk818_irqs),
501         .num_regs = 2,
502         .irq_reg_stride = 2,
503         .status_base = RK818_INT_STS_REG1,
504         .mask_base = RK818_INT_STS_MSK_REG1,
505         .ack_base = RK818_INT_STS_REG1,
506         .init_ack_masked = true,
507 };
508
509 static int rk808_power_off(struct sys_off_data *data)
510 {
511         struct rk808 *rk808 = data->cb_data;
512         int ret;
513         unsigned int reg, bit;
514
515         switch (rk808->variant) {
516         case RK805_ID:
517                 reg = RK805_DEV_CTRL_REG;
518                 bit = DEV_OFF;
519                 break;
520         case RK806_ID:
521                 reg = RK806_SYS_CFG3;
522                 bit = DEV_OFF;
523                 break;
524         case RK808_ID:
525                 reg = RK808_DEVCTRL_REG,
526                 bit = DEV_OFF_RST;
527                 break;
528         case RK809_ID:
529         case RK817_ID:
530                 reg = RK817_SYS_CFG(3);
531                 bit = DEV_OFF;
532                 break;
533         case RK818_ID:
534                 reg = RK818_DEVCTRL_REG;
535                 bit = DEV_OFF;
536                 break;
537         default:
538                 return NOTIFY_DONE;
539         }
540         ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
541         if (ret)
542                 dev_err(rk808->dev, "Failed to shutdown device!\n");
543
544         return NOTIFY_DONE;
545 }
546
547 static int rk808_restart(struct sys_off_data *data)
548 {
549         struct rk808 *rk808 = data->cb_data;
550         unsigned int reg, bit;
551         int ret;
552
553         switch (rk808->variant) {
554         case RK809_ID:
555         case RK817_ID:
556                 reg = RK817_SYS_CFG(3);
557                 bit = DEV_RST;
558                 break;
559
560         default:
561                 return NOTIFY_DONE;
562         }
563         ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
564         if (ret)
565                 dev_err(rk808->dev, "Failed to restart device!\n");
566
567         return NOTIFY_DONE;
568 }
569
570 void rk8xx_shutdown(struct device *dev)
571 {
572         struct rk808 *rk808 = dev_get_drvdata(dev);
573         int ret;
574
575         switch (rk808->variant) {
576         case RK805_ID:
577                 ret = regmap_update_bits(rk808->regmap,
578                                          RK805_GPIO_IO_POL_REG,
579                                          SLP_SD_MSK,
580                                          SHUTDOWN_FUN);
581                 break;
582         case RK809_ID:
583         case RK817_ID:
584                 ret = regmap_update_bits(rk808->regmap,
585                                          RK817_SYS_CFG(3),
586                                          RK817_SLPPIN_FUNC_MSK,
587                                          SLPPIN_DN_FUN);
588                 break;
589         default:
590                 return;
591         }
592         if (ret)
593                 dev_warn(dev,
594                          "Cannot switch to power down function\n");
595 }
596 EXPORT_SYMBOL_GPL(rk8xx_shutdown);
597
598 int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap)
599 {
600         struct rk808 *rk808;
601         const struct rk808_reg_data *pre_init_reg;
602         const struct mfd_cell *cells;
603         int dual_support = 0;
604         int nr_pre_init_regs;
605         int nr_cells;
606         int ret;
607         int i;
608
609         rk808 = devm_kzalloc(dev, sizeof(*rk808), GFP_KERNEL);
610         if (!rk808)
611                 return -ENOMEM;
612         rk808->dev = dev;
613         rk808->variant = variant;
614         rk808->regmap = regmap;
615         dev_set_drvdata(dev, rk808);
616
617         switch (rk808->variant) {
618         case RK805_ID:
619                 rk808->regmap_irq_chip = &rk805_irq_chip;
620                 pre_init_reg = rk805_pre_init_reg;
621                 nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg);
622                 cells = rk805s;
623                 nr_cells = ARRAY_SIZE(rk805s);
624                 break;
625         case RK806_ID:
626                 rk808->regmap_irq_chip = &rk806_irq_chip;
627                 pre_init_reg = rk806_pre_init_reg;
628                 nr_pre_init_regs = ARRAY_SIZE(rk806_pre_init_reg);
629                 cells = rk806s;
630                 nr_cells = ARRAY_SIZE(rk806s);
631                 dual_support = IRQF_SHARED;
632                 break;
633         case RK808_ID:
634                 rk808->regmap_irq_chip = &rk808_irq_chip;
635                 pre_init_reg = rk808_pre_init_reg;
636                 nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg);
637                 cells = rk808s;
638                 nr_cells = ARRAY_SIZE(rk808s);
639                 break;
640         case RK818_ID:
641                 rk808->regmap_irq_chip = &rk818_irq_chip;
642                 pre_init_reg = rk818_pre_init_reg;
643                 nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg);
644                 cells = rk818s;
645                 nr_cells = ARRAY_SIZE(rk818s);
646                 break;
647         case RK809_ID:
648         case RK817_ID:
649                 rk808->regmap_irq_chip = &rk817_irq_chip;
650                 pre_init_reg = rk817_pre_init_reg;
651                 nr_pre_init_regs = ARRAY_SIZE(rk817_pre_init_reg);
652                 cells = rk817s;
653                 nr_cells = ARRAY_SIZE(rk817s);
654                 break;
655         default:
656                 dev_err(dev, "Unsupported RK8XX ID %lu\n", rk808->variant);
657                 return -EINVAL;
658         }
659
660         if (!irq)
661                 return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n");
662
663         ret = devm_regmap_add_irq_chip(dev, rk808->regmap, irq,
664                                        IRQF_ONESHOT | dual_support, -1,
665                                        rk808->regmap_irq_chip, &rk808->irq_data);
666         if (ret)
667                 return dev_err_probe(dev, ret, "Failed to add irq_chip\n");
668
669         for (i = 0; i < nr_pre_init_regs; i++) {
670                 ret = regmap_update_bits(rk808->regmap,
671                                         pre_init_reg[i].addr,
672                                         pre_init_reg[i].mask,
673                                         pre_init_reg[i].value);
674                 if (ret)
675                         return dev_err_probe(dev, ret, "0x%x write err\n",
676                                              pre_init_reg[i].addr);
677         }
678
679         ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, cells, nr_cells, NULL, 0,
680                               regmap_irq_get_domain(rk808->irq_data));
681         if (ret)
682                 return dev_err_probe(dev, ret, "failed to add MFD devices\n");
683
684         if (device_property_read_bool(dev, "rockchip,system-power-controller") ||
685             device_property_read_bool(dev, "system-power-controller")) {
686                 ret = devm_register_sys_off_handler(dev,
687                                     SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH,
688                                     &rk808_power_off, rk808);
689                 if (ret)
690                         return dev_err_probe(dev, ret,
691                                              "failed to register poweroff handler\n");
692
693                 switch (rk808->variant) {
694                 case RK809_ID:
695                 case RK817_ID:
696                         ret = devm_register_sys_off_handler(dev,
697                                                             SYS_OFF_MODE_RESTART, SYS_OFF_PRIO_HIGH,
698                                                             &rk808_restart, rk808);
699                         if (ret)
700                                 dev_warn(dev, "failed to register rst handler, %d\n", ret);
701                         break;
702                 default:
703                         dev_dbg(dev, "pmic controlled board reset not supported\n");
704                         break;
705                 }
706         }
707
708         return 0;
709 }
710 EXPORT_SYMBOL_GPL(rk8xx_probe);
711
712 int rk8xx_suspend(struct device *dev)
713 {
714         struct rk808 *rk808 = dev_get_drvdata(dev);
715         int ret = 0;
716
717         switch (rk808->variant) {
718         case RK805_ID:
719                 ret = regmap_update_bits(rk808->regmap,
720                                          RK805_GPIO_IO_POL_REG,
721                                          SLP_SD_MSK,
722                                          SLEEP_FUN);
723                 break;
724         case RK809_ID:
725         case RK817_ID:
726                 ret = regmap_update_bits(rk808->regmap,
727                                          RK817_SYS_CFG(3),
728                                          RK817_SLPPIN_FUNC_MSK,
729                                          SLPPIN_SLP_FUN);
730                 break;
731         default:
732                 break;
733         }
734
735         return ret;
736 }
737 EXPORT_SYMBOL_GPL(rk8xx_suspend);
738
739 int rk8xx_resume(struct device *dev)
740 {
741         struct rk808 *rk808 = dev_get_drvdata(dev);
742         int ret = 0;
743
744         switch (rk808->variant) {
745         case RK809_ID:
746         case RK817_ID:
747                 ret = regmap_update_bits(rk808->regmap,
748                                          RK817_SYS_CFG(3),
749                                          RK817_SLPPIN_FUNC_MSK,
750                                          SLPPIN_NULL_FUN);
751                 break;
752         default:
753                 break;
754         }
755
756         return ret;
757 }
758 EXPORT_SYMBOL_GPL(rk8xx_resume);
759
760 MODULE_LICENSE("GPL");
761 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
762 MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
763 MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
764 MODULE_DESCRIPTION("RK8xx PMIC core");