162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * MFD core driver for Rockchip RK8XX
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
662306a36Sopenharmony_ci * Copyright (C) 2016 PHYTEC Messtechnik GmbH
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * Author: Chris Zhong <zyw@rock-chips.com>
962306a36Sopenharmony_ci * Author: Zhang Qing <zhangqing@rock-chips.com>
1062306a36Sopenharmony_ci * Author: Wadim Egorov <w.egorov@phytec.de>
1162306a36Sopenharmony_ci */
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <linux/interrupt.h>
1462306a36Sopenharmony_ci#include <linux/mfd/rk808.h>
1562306a36Sopenharmony_ci#include <linux/mfd/core.h>
1662306a36Sopenharmony_ci#include <linux/module.h>
1762306a36Sopenharmony_ci#include <linux/property.h>
1862306a36Sopenharmony_ci#include <linux/regmap.h>
1962306a36Sopenharmony_ci#include <linux/reboot.h>
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_cistruct rk808_reg_data {
2262306a36Sopenharmony_ci	int addr;
2362306a36Sopenharmony_ci	int mask;
2462306a36Sopenharmony_ci	int value;
2562306a36Sopenharmony_ci};
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistatic const struct resource rtc_resources[] = {
2862306a36Sopenharmony_ci	DEFINE_RES_IRQ(RK808_IRQ_RTC_ALARM),
2962306a36Sopenharmony_ci};
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_cistatic const struct resource rk817_rtc_resources[] = {
3262306a36Sopenharmony_ci	DEFINE_RES_IRQ(RK817_IRQ_RTC_ALARM),
3362306a36Sopenharmony_ci};
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_cistatic const struct resource rk805_key_resources[] = {
3662306a36Sopenharmony_ci	DEFINE_RES_IRQ(RK805_IRQ_PWRON_RISE),
3762306a36Sopenharmony_ci	DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL),
3862306a36Sopenharmony_ci};
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_cistatic struct resource rk806_pwrkey_resources[] = {
4162306a36Sopenharmony_ci	DEFINE_RES_IRQ(RK806_IRQ_PWRON_FALL),
4262306a36Sopenharmony_ci	DEFINE_RES_IRQ(RK806_IRQ_PWRON_RISE),
4362306a36Sopenharmony_ci};
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_cistatic const struct resource rk817_pwrkey_resources[] = {
4662306a36Sopenharmony_ci	DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE),
4762306a36Sopenharmony_ci	DEFINE_RES_IRQ(RK817_IRQ_PWRON_FALL),
4862306a36Sopenharmony_ci};
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_cistatic const struct resource rk817_charger_resources[] = {
5162306a36Sopenharmony_ci	DEFINE_RES_IRQ(RK817_IRQ_PLUG_IN),
5262306a36Sopenharmony_ci	DEFINE_RES_IRQ(RK817_IRQ_PLUG_OUT),
5362306a36Sopenharmony_ci};
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_cistatic const struct mfd_cell rk805s[] = {
5662306a36Sopenharmony_ci	{ .name = "rk808-clkout", },
5762306a36Sopenharmony_ci	{ .name = "rk808-regulator", },
5862306a36Sopenharmony_ci	{ .name = "rk805-pinctrl", },
5962306a36Sopenharmony_ci	{
6062306a36Sopenharmony_ci		.name = "rk808-rtc",
6162306a36Sopenharmony_ci		.num_resources = ARRAY_SIZE(rtc_resources),
6262306a36Sopenharmony_ci		.resources = &rtc_resources[0],
6362306a36Sopenharmony_ci	},
6462306a36Sopenharmony_ci	{	.name = "rk805-pwrkey",
6562306a36Sopenharmony_ci		.num_resources = ARRAY_SIZE(rk805_key_resources),
6662306a36Sopenharmony_ci		.resources = &rk805_key_resources[0],
6762306a36Sopenharmony_ci	},
6862306a36Sopenharmony_ci};
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_cistatic const struct mfd_cell rk806s[] = {
7162306a36Sopenharmony_ci	{ .name = "rk805-pinctrl", },
7262306a36Sopenharmony_ci	{ .name = "rk808-regulator", },
7362306a36Sopenharmony_ci	{
7462306a36Sopenharmony_ci		.name = "rk805-pwrkey",
7562306a36Sopenharmony_ci		.resources = rk806_pwrkey_resources,
7662306a36Sopenharmony_ci		.num_resources = ARRAY_SIZE(rk806_pwrkey_resources),
7762306a36Sopenharmony_ci	},
7862306a36Sopenharmony_ci};
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_cistatic const struct mfd_cell rk808s[] = {
8162306a36Sopenharmony_ci	{ .name = "rk808-clkout", },
8262306a36Sopenharmony_ci	{ .name = "rk808-regulator", },
8362306a36Sopenharmony_ci	{
8462306a36Sopenharmony_ci		.name = "rk808-rtc",
8562306a36Sopenharmony_ci		.num_resources = ARRAY_SIZE(rtc_resources),
8662306a36Sopenharmony_ci		.resources = rtc_resources,
8762306a36Sopenharmony_ci	},
8862306a36Sopenharmony_ci};
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_cistatic const struct mfd_cell rk817s[] = {
9162306a36Sopenharmony_ci	{ .name = "rk808-clkout", },
9262306a36Sopenharmony_ci	{ .name = "rk808-regulator", },
9362306a36Sopenharmony_ci	{
9462306a36Sopenharmony_ci		.name = "rk805-pwrkey",
9562306a36Sopenharmony_ci		.num_resources = ARRAY_SIZE(rk817_pwrkey_resources),
9662306a36Sopenharmony_ci		.resources = &rk817_pwrkey_resources[0],
9762306a36Sopenharmony_ci	},
9862306a36Sopenharmony_ci	{
9962306a36Sopenharmony_ci		.name = "rk808-rtc",
10062306a36Sopenharmony_ci		.num_resources = ARRAY_SIZE(rk817_rtc_resources),
10162306a36Sopenharmony_ci		.resources = &rk817_rtc_resources[0],
10262306a36Sopenharmony_ci	},
10362306a36Sopenharmony_ci	{ .name = "rk817-codec", },
10462306a36Sopenharmony_ci	{
10562306a36Sopenharmony_ci		.name = "rk817-charger",
10662306a36Sopenharmony_ci		.num_resources = ARRAY_SIZE(rk817_charger_resources),
10762306a36Sopenharmony_ci		.resources = &rk817_charger_resources[0],
10862306a36Sopenharmony_ci	},
10962306a36Sopenharmony_ci};
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_cistatic const struct mfd_cell rk818s[] = {
11262306a36Sopenharmony_ci	{ .name = "rk808-clkout", },
11362306a36Sopenharmony_ci	{ .name = "rk808-regulator", },
11462306a36Sopenharmony_ci	{
11562306a36Sopenharmony_ci		.name = "rk808-rtc",
11662306a36Sopenharmony_ci		.num_resources = ARRAY_SIZE(rtc_resources),
11762306a36Sopenharmony_ci		.resources = rtc_resources,
11862306a36Sopenharmony_ci	},
11962306a36Sopenharmony_ci};
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_cistatic const struct rk808_reg_data rk805_pre_init_reg[] = {
12262306a36Sopenharmony_ci	{RK805_BUCK1_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
12362306a36Sopenharmony_ci				 RK805_BUCK1_2_ILMAX_4000MA},
12462306a36Sopenharmony_ci	{RK805_BUCK2_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
12562306a36Sopenharmony_ci				 RK805_BUCK1_2_ILMAX_4000MA},
12662306a36Sopenharmony_ci	{RK805_BUCK3_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK,
12762306a36Sopenharmony_ci				 RK805_BUCK3_ILMAX_3000MA},
12862306a36Sopenharmony_ci	{RK805_BUCK4_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK,
12962306a36Sopenharmony_ci				 RK805_BUCK4_ILMAX_3500MA},
13062306a36Sopenharmony_ci	{RK805_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_400MA},
13162306a36Sopenharmony_ci	{RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C},
13262306a36Sopenharmony_ci};
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_cistatic const struct rk808_reg_data rk806_pre_init_reg[] = {
13562306a36Sopenharmony_ci	{ RK806_GPIO_INT_CONFIG, RK806_INT_POL_MSK, RK806_INT_POL_L },
13662306a36Sopenharmony_ci	{ RK806_SYS_CFG3, RK806_SLAVE_RESTART_FUN_MSK, RK806_SLAVE_RESTART_FUN_EN },
13762306a36Sopenharmony_ci	{ RK806_SYS_OPTION, RK806_SYS_ENB2_2M_MSK, RK806_SYS_ENB2_2M_EN },
13862306a36Sopenharmony_ci};
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_cistatic const struct rk808_reg_data rk808_pre_init_reg[] = {
14162306a36Sopenharmony_ci	{ RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_150MA },
14262306a36Sopenharmony_ci	{ RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_200MA },
14362306a36Sopenharmony_ci	{ RK808_BOOST_CONFIG_REG, BOOST_ILMIN_MASK, BOOST_ILMIN_100MA },
14462306a36Sopenharmony_ci	{ RK808_BUCK1_CONFIG_REG, BUCK1_RATE_MASK,  BUCK_ILMIN_200MA },
14562306a36Sopenharmony_ci	{ RK808_BUCK2_CONFIG_REG, BUCK2_RATE_MASK,  BUCK_ILMIN_200MA },
14662306a36Sopenharmony_ci	{ RK808_DCDC_UV_ACT_REG,  BUCK_UV_ACT_MASK, BUCK_UV_ACT_DISABLE},
14762306a36Sopenharmony_ci	{ RK808_VB_MON_REG,       MASK_ALL,         VB_LO_ACT |
14862306a36Sopenharmony_ci						    VB_LO_SEL_3500MV },
14962306a36Sopenharmony_ci};
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_cistatic const struct rk808_reg_data rk817_pre_init_reg[] = {
15262306a36Sopenharmony_ci	{RK817_RTC_CTRL_REG, RTC_STOP, RTC_STOP},
15362306a36Sopenharmony_ci	/* Codec specific registers */
15462306a36Sopenharmony_ci	{ RK817_CODEC_DTOP_VUCTL, MASK_ALL, 0x03 },
15562306a36Sopenharmony_ci	{ RK817_CODEC_DTOP_VUCTIME, MASK_ALL, 0x00 },
15662306a36Sopenharmony_ci	{ RK817_CODEC_DTOP_LPT_SRST, MASK_ALL, 0x00 },
15762306a36Sopenharmony_ci	{ RK817_CODEC_DTOP_DIGEN_CLKE, MASK_ALL, 0x00 },
15862306a36Sopenharmony_ci	/* from vendor driver, CODEC_AREF_RTCFG0 not defined in data sheet */
15962306a36Sopenharmony_ci	{ RK817_CODEC_AREF_RTCFG0, MASK_ALL, 0x00 },
16062306a36Sopenharmony_ci	{ RK817_CODEC_AREF_RTCFG1, MASK_ALL, 0x06 },
16162306a36Sopenharmony_ci	{ RK817_CODEC_AADC_CFG0, MASK_ALL, 0xc8 },
16262306a36Sopenharmony_ci	/* from vendor driver, CODEC_AADC_CFG1 not defined in data sheet */
16362306a36Sopenharmony_ci	{ RK817_CODEC_AADC_CFG1, MASK_ALL, 0x00 },
16462306a36Sopenharmony_ci	{ RK817_CODEC_DADC_VOLL, MASK_ALL, 0x00 },
16562306a36Sopenharmony_ci	{ RK817_CODEC_DADC_VOLR, MASK_ALL, 0x00 },
16662306a36Sopenharmony_ci	{ RK817_CODEC_DADC_SR_ACL0, MASK_ALL, 0x00 },
16762306a36Sopenharmony_ci	{ RK817_CODEC_DADC_ALC1, MASK_ALL, 0x00 },
16862306a36Sopenharmony_ci	{ RK817_CODEC_DADC_ALC2, MASK_ALL, 0x00 },
16962306a36Sopenharmony_ci	{ RK817_CODEC_DADC_NG, MASK_ALL, 0x00 },
17062306a36Sopenharmony_ci	{ RK817_CODEC_DADC_HPF, MASK_ALL, 0x00 },
17162306a36Sopenharmony_ci	{ RK817_CODEC_DADC_RVOLL, MASK_ALL, 0xff },
17262306a36Sopenharmony_ci	{ RK817_CODEC_DADC_RVOLR, MASK_ALL, 0xff },
17362306a36Sopenharmony_ci	{ RK817_CODEC_AMIC_CFG0, MASK_ALL, 0x70 },
17462306a36Sopenharmony_ci	{ RK817_CODEC_AMIC_CFG1, MASK_ALL, 0x00 },
17562306a36Sopenharmony_ci	{ RK817_CODEC_DMIC_PGA_GAIN, MASK_ALL, 0x66 },
17662306a36Sopenharmony_ci	{ RK817_CODEC_DMIC_LMT1, MASK_ALL, 0x00 },
17762306a36Sopenharmony_ci	{ RK817_CODEC_DMIC_LMT2, MASK_ALL, 0x00 },
17862306a36Sopenharmony_ci	{ RK817_CODEC_DMIC_NG1, MASK_ALL, 0x00 },
17962306a36Sopenharmony_ci	{ RK817_CODEC_DMIC_NG2, MASK_ALL, 0x00 },
18062306a36Sopenharmony_ci	/* from vendor driver, CODEC_ADAC_CFG0 not defined in data sheet */
18162306a36Sopenharmony_ci	{ RK817_CODEC_ADAC_CFG0, MASK_ALL, 0x00 },
18262306a36Sopenharmony_ci	{ RK817_CODEC_ADAC_CFG1, MASK_ALL, 0x07 },
18362306a36Sopenharmony_ci	{ RK817_CODEC_DDAC_POPD_DACST, MASK_ALL, 0x82 },
18462306a36Sopenharmony_ci	{ RK817_CODEC_DDAC_VOLL, MASK_ALL, 0x00 },
18562306a36Sopenharmony_ci	{ RK817_CODEC_DDAC_VOLR, MASK_ALL, 0x00 },
18662306a36Sopenharmony_ci	{ RK817_CODEC_DDAC_SR_LMT0, MASK_ALL, 0x00 },
18762306a36Sopenharmony_ci	{ RK817_CODEC_DDAC_LMT1, MASK_ALL, 0x00 },
18862306a36Sopenharmony_ci	{ RK817_CODEC_DDAC_LMT2, MASK_ALL, 0x00 },
18962306a36Sopenharmony_ci	{ RK817_CODEC_DDAC_MUTE_MIXCTL, MASK_ALL, 0xa0 },
19062306a36Sopenharmony_ci	{ RK817_CODEC_DDAC_RVOLL, MASK_ALL, 0xff },
19162306a36Sopenharmony_ci	{ RK817_CODEC_DADC_RVOLR, MASK_ALL, 0xff },
19262306a36Sopenharmony_ci	{ RK817_CODEC_AMIC_CFG0, MASK_ALL, 0x70 },
19362306a36Sopenharmony_ci	{ RK817_CODEC_AMIC_CFG1, MASK_ALL, 0x00 },
19462306a36Sopenharmony_ci	{ RK817_CODEC_DMIC_PGA_GAIN, MASK_ALL, 0x66 },
19562306a36Sopenharmony_ci	{ RK817_CODEC_DMIC_LMT1, MASK_ALL, 0x00 },
19662306a36Sopenharmony_ci	{ RK817_CODEC_DMIC_LMT2, MASK_ALL, 0x00 },
19762306a36Sopenharmony_ci	{ RK817_CODEC_DMIC_NG1, MASK_ALL, 0x00 },
19862306a36Sopenharmony_ci	{ RK817_CODEC_DMIC_NG2, MASK_ALL, 0x00 },
19962306a36Sopenharmony_ci	/* from vendor driver, CODEC_ADAC_CFG0 not defined in data sheet */
20062306a36Sopenharmony_ci	{ RK817_CODEC_ADAC_CFG0, MASK_ALL, 0x00 },
20162306a36Sopenharmony_ci	{ RK817_CODEC_ADAC_CFG1, MASK_ALL, 0x07 },
20262306a36Sopenharmony_ci	{ RK817_CODEC_DDAC_POPD_DACST, MASK_ALL, 0x82 },
20362306a36Sopenharmony_ci	{ RK817_CODEC_DDAC_VOLL, MASK_ALL, 0x00 },
20462306a36Sopenharmony_ci	{ RK817_CODEC_DDAC_VOLR, MASK_ALL, 0x00 },
20562306a36Sopenharmony_ci	{ RK817_CODEC_DDAC_SR_LMT0, MASK_ALL, 0x00 },
20662306a36Sopenharmony_ci	{ RK817_CODEC_DDAC_LMT1, MASK_ALL, 0x00 },
20762306a36Sopenharmony_ci	{ RK817_CODEC_DDAC_LMT2, MASK_ALL, 0x00 },
20862306a36Sopenharmony_ci	{ RK817_CODEC_DDAC_MUTE_MIXCTL, MASK_ALL, 0xa0 },
20962306a36Sopenharmony_ci	{ RK817_CODEC_DDAC_RVOLL, MASK_ALL, 0xff },
21062306a36Sopenharmony_ci	{ RK817_CODEC_DDAC_RVOLR, MASK_ALL, 0xff },
21162306a36Sopenharmony_ci	{ RK817_CODEC_AHP_ANTI0, MASK_ALL, 0x00 },
21262306a36Sopenharmony_ci	{ RK817_CODEC_AHP_ANTI1, MASK_ALL, 0x00 },
21362306a36Sopenharmony_ci	{ RK817_CODEC_AHP_CFG0, MASK_ALL, 0xe0 },
21462306a36Sopenharmony_ci	{ RK817_CODEC_AHP_CFG1, MASK_ALL, 0x1f },
21562306a36Sopenharmony_ci	{ RK817_CODEC_AHP_CP, MASK_ALL, 0x09 },
21662306a36Sopenharmony_ci	{ RK817_CODEC_ACLASSD_CFG1, MASK_ALL, 0x69 },
21762306a36Sopenharmony_ci	{ RK817_CODEC_ACLASSD_CFG2, MASK_ALL, 0x44 },
21862306a36Sopenharmony_ci	{ RK817_CODEC_APLL_CFG0, MASK_ALL, 0x04 },
21962306a36Sopenharmony_ci	{ RK817_CODEC_APLL_CFG1, MASK_ALL, 0x00 },
22062306a36Sopenharmony_ci	{ RK817_CODEC_APLL_CFG2, MASK_ALL, 0x30 },
22162306a36Sopenharmony_ci	{ RK817_CODEC_APLL_CFG3, MASK_ALL, 0x19 },
22262306a36Sopenharmony_ci	{ RK817_CODEC_APLL_CFG4, MASK_ALL, 0x65 },
22362306a36Sopenharmony_ci	{ RK817_CODEC_APLL_CFG5, MASK_ALL, 0x01 },
22462306a36Sopenharmony_ci	{ RK817_CODEC_DI2S_CKM, MASK_ALL, 0x01 },
22562306a36Sopenharmony_ci	{ RK817_CODEC_DI2S_RSD, MASK_ALL, 0x00 },
22662306a36Sopenharmony_ci	{ RK817_CODEC_DI2S_RXCR1, MASK_ALL, 0x00 },
22762306a36Sopenharmony_ci	{ RK817_CODEC_DI2S_RXCR2, MASK_ALL, 0x17 },
22862306a36Sopenharmony_ci	{ RK817_CODEC_DI2S_RXCMD_TSD, MASK_ALL, 0x00 },
22962306a36Sopenharmony_ci	{ RK817_CODEC_DI2S_TXCR1, MASK_ALL, 0x00 },
23062306a36Sopenharmony_ci	{ RK817_CODEC_DI2S_TXCR2, MASK_ALL, 0x17 },
23162306a36Sopenharmony_ci	{ RK817_CODEC_DI2S_TXCR3_TXCMD, MASK_ALL, 0x00 },
23262306a36Sopenharmony_ci	{RK817_GPIO_INT_CFG, RK817_INT_POL_MSK, RK817_INT_POL_L},
23362306a36Sopenharmony_ci	{RK817_SYS_CFG(1), RK817_HOTDIE_TEMP_MSK | RK817_TSD_TEMP_MSK,
23462306a36Sopenharmony_ci					   RK817_HOTDIE_105 | RK817_TSD_140},
23562306a36Sopenharmony_ci};
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_cistatic const struct rk808_reg_data rk818_pre_init_reg[] = {
23862306a36Sopenharmony_ci	/* improve efficiency */
23962306a36Sopenharmony_ci	{ RK818_BUCK2_CONFIG_REG, BUCK2_RATE_MASK,  BUCK_ILMIN_250MA },
24062306a36Sopenharmony_ci	{ RK818_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_250MA },
24162306a36Sopenharmony_ci	{ RK818_BOOST_CONFIG_REG, BOOST_ILMIN_MASK, BOOST_ILMIN_100MA },
24262306a36Sopenharmony_ci	{ RK818_USB_CTRL_REG,	  RK818_USB_ILIM_SEL_MASK,
24362306a36Sopenharmony_ci						    RK818_USB_ILMIN_2000MA },
24462306a36Sopenharmony_ci	/* close charger when usb lower then 3.4V */
24562306a36Sopenharmony_ci	{ RK818_USB_CTRL_REG,	  RK818_USB_CHG_SD_VSEL_MASK,
24662306a36Sopenharmony_ci						    (0x7 << 4) },
24762306a36Sopenharmony_ci	/* no action when vref */
24862306a36Sopenharmony_ci	{ RK818_H5V_EN_REG,	  BIT(1),	    RK818_REF_RDY_CTRL },
24962306a36Sopenharmony_ci	/* enable HDMI 5V */
25062306a36Sopenharmony_ci	{ RK818_H5V_EN_REG,	  BIT(0),	    RK818_H5V_EN },
25162306a36Sopenharmony_ci	{ RK808_VB_MON_REG,	  MASK_ALL,	    VB_LO_ACT |
25262306a36Sopenharmony_ci						    VB_LO_SEL_3500MV },
25362306a36Sopenharmony_ci};
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_cistatic const struct regmap_irq rk805_irqs[] = {
25662306a36Sopenharmony_ci	[RK805_IRQ_PWRON_RISE] = {
25762306a36Sopenharmony_ci		.mask = RK805_IRQ_PWRON_RISE_MSK,
25862306a36Sopenharmony_ci		.reg_offset = 0,
25962306a36Sopenharmony_ci	},
26062306a36Sopenharmony_ci	[RK805_IRQ_VB_LOW] = {
26162306a36Sopenharmony_ci		.mask = RK805_IRQ_VB_LOW_MSK,
26262306a36Sopenharmony_ci		.reg_offset = 0,
26362306a36Sopenharmony_ci	},
26462306a36Sopenharmony_ci	[RK805_IRQ_PWRON] = {
26562306a36Sopenharmony_ci		.mask = RK805_IRQ_PWRON_MSK,
26662306a36Sopenharmony_ci		.reg_offset = 0,
26762306a36Sopenharmony_ci	},
26862306a36Sopenharmony_ci	[RK805_IRQ_PWRON_LP] = {
26962306a36Sopenharmony_ci		.mask = RK805_IRQ_PWRON_LP_MSK,
27062306a36Sopenharmony_ci		.reg_offset = 0,
27162306a36Sopenharmony_ci	},
27262306a36Sopenharmony_ci	[RK805_IRQ_HOTDIE] = {
27362306a36Sopenharmony_ci		.mask = RK805_IRQ_HOTDIE_MSK,
27462306a36Sopenharmony_ci		.reg_offset = 0,
27562306a36Sopenharmony_ci	},
27662306a36Sopenharmony_ci	[RK805_IRQ_RTC_ALARM] = {
27762306a36Sopenharmony_ci		.mask = RK805_IRQ_RTC_ALARM_MSK,
27862306a36Sopenharmony_ci		.reg_offset = 0,
27962306a36Sopenharmony_ci	},
28062306a36Sopenharmony_ci	[RK805_IRQ_RTC_PERIOD] = {
28162306a36Sopenharmony_ci		.mask = RK805_IRQ_RTC_PERIOD_MSK,
28262306a36Sopenharmony_ci		.reg_offset = 0,
28362306a36Sopenharmony_ci	},
28462306a36Sopenharmony_ci	[RK805_IRQ_PWRON_FALL] = {
28562306a36Sopenharmony_ci		.mask = RK805_IRQ_PWRON_FALL_MSK,
28662306a36Sopenharmony_ci		.reg_offset = 0,
28762306a36Sopenharmony_ci	},
28862306a36Sopenharmony_ci};
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_cistatic const struct regmap_irq rk806_irqs[] = {
29162306a36Sopenharmony_ci	/* INT_STS0 IRQs */
29262306a36Sopenharmony_ci	REGMAP_IRQ_REG(RK806_IRQ_PWRON_FALL, 0, RK806_INT_STS_PWRON_FALL),
29362306a36Sopenharmony_ci	REGMAP_IRQ_REG(RK806_IRQ_PWRON_RISE, 0, RK806_INT_STS_PWRON_RISE),
29462306a36Sopenharmony_ci	REGMAP_IRQ_REG(RK806_IRQ_PWRON, 0, RK806_INT_STS_PWRON),
29562306a36Sopenharmony_ci	REGMAP_IRQ_REG(RK806_IRQ_PWRON_LP, 0, RK806_INT_STS_PWRON_LP),
29662306a36Sopenharmony_ci	REGMAP_IRQ_REG(RK806_IRQ_HOTDIE, 0, RK806_INT_STS_HOTDIE),
29762306a36Sopenharmony_ci	REGMAP_IRQ_REG(RK806_IRQ_VDC_RISE, 0, RK806_INT_STS_VDC_RISE),
29862306a36Sopenharmony_ci	REGMAP_IRQ_REG(RK806_IRQ_VDC_FALL, 0, RK806_INT_STS_VDC_FALL),
29962306a36Sopenharmony_ci	REGMAP_IRQ_REG(RK806_IRQ_VB_LO, 0, RK806_INT_STS_VB_LO),
30062306a36Sopenharmony_ci	/* INT_STS1 IRQs */
30162306a36Sopenharmony_ci	REGMAP_IRQ_REG(RK806_IRQ_REV0, 1, RK806_INT_STS_REV0),
30262306a36Sopenharmony_ci	REGMAP_IRQ_REG(RK806_IRQ_REV1, 1, RK806_INT_STS_REV1),
30362306a36Sopenharmony_ci	REGMAP_IRQ_REG(RK806_IRQ_REV2, 1, RK806_INT_STS_REV2),
30462306a36Sopenharmony_ci	REGMAP_IRQ_REG(RK806_IRQ_CRC_ERROR, 1, RK806_INT_STS_CRC_ERROR),
30562306a36Sopenharmony_ci	REGMAP_IRQ_REG(RK806_IRQ_SLP3_GPIO, 1, RK806_INT_STS_SLP3_GPIO),
30662306a36Sopenharmony_ci	REGMAP_IRQ_REG(RK806_IRQ_SLP2_GPIO, 1, RK806_INT_STS_SLP2_GPIO),
30762306a36Sopenharmony_ci	REGMAP_IRQ_REG(RK806_IRQ_SLP1_GPIO, 1, RK806_INT_STS_SLP1_GPIO),
30862306a36Sopenharmony_ci	REGMAP_IRQ_REG(RK806_IRQ_WDT, 1, RK806_INT_STS_WDT),
30962306a36Sopenharmony_ci};
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_cistatic const struct regmap_irq rk808_irqs[] = {
31262306a36Sopenharmony_ci	/* INT_STS */
31362306a36Sopenharmony_ci	[RK808_IRQ_VOUT_LO] = {
31462306a36Sopenharmony_ci		.mask = RK808_IRQ_VOUT_LO_MSK,
31562306a36Sopenharmony_ci		.reg_offset = 0,
31662306a36Sopenharmony_ci	},
31762306a36Sopenharmony_ci	[RK808_IRQ_VB_LO] = {
31862306a36Sopenharmony_ci		.mask = RK808_IRQ_VB_LO_MSK,
31962306a36Sopenharmony_ci		.reg_offset = 0,
32062306a36Sopenharmony_ci	},
32162306a36Sopenharmony_ci	[RK808_IRQ_PWRON] = {
32262306a36Sopenharmony_ci		.mask = RK808_IRQ_PWRON_MSK,
32362306a36Sopenharmony_ci		.reg_offset = 0,
32462306a36Sopenharmony_ci	},
32562306a36Sopenharmony_ci	[RK808_IRQ_PWRON_LP] = {
32662306a36Sopenharmony_ci		.mask = RK808_IRQ_PWRON_LP_MSK,
32762306a36Sopenharmony_ci		.reg_offset = 0,
32862306a36Sopenharmony_ci	},
32962306a36Sopenharmony_ci	[RK808_IRQ_HOTDIE] = {
33062306a36Sopenharmony_ci		.mask = RK808_IRQ_HOTDIE_MSK,
33162306a36Sopenharmony_ci		.reg_offset = 0,
33262306a36Sopenharmony_ci	},
33362306a36Sopenharmony_ci	[RK808_IRQ_RTC_ALARM] = {
33462306a36Sopenharmony_ci		.mask = RK808_IRQ_RTC_ALARM_MSK,
33562306a36Sopenharmony_ci		.reg_offset = 0,
33662306a36Sopenharmony_ci	},
33762306a36Sopenharmony_ci	[RK808_IRQ_RTC_PERIOD] = {
33862306a36Sopenharmony_ci		.mask = RK808_IRQ_RTC_PERIOD_MSK,
33962306a36Sopenharmony_ci		.reg_offset = 0,
34062306a36Sopenharmony_ci	},
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci	/* INT_STS2 */
34362306a36Sopenharmony_ci	[RK808_IRQ_PLUG_IN_INT] = {
34462306a36Sopenharmony_ci		.mask = RK808_IRQ_PLUG_IN_INT_MSK,
34562306a36Sopenharmony_ci		.reg_offset = 1,
34662306a36Sopenharmony_ci	},
34762306a36Sopenharmony_ci	[RK808_IRQ_PLUG_OUT_INT] = {
34862306a36Sopenharmony_ci		.mask = RK808_IRQ_PLUG_OUT_INT_MSK,
34962306a36Sopenharmony_ci		.reg_offset = 1,
35062306a36Sopenharmony_ci	},
35162306a36Sopenharmony_ci};
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_cistatic const struct regmap_irq rk818_irqs[] = {
35462306a36Sopenharmony_ci	/* INT_STS */
35562306a36Sopenharmony_ci	[RK818_IRQ_VOUT_LO] = {
35662306a36Sopenharmony_ci		.mask = RK818_IRQ_VOUT_LO_MSK,
35762306a36Sopenharmony_ci		.reg_offset = 0,
35862306a36Sopenharmony_ci	},
35962306a36Sopenharmony_ci	[RK818_IRQ_VB_LO] = {
36062306a36Sopenharmony_ci		.mask = RK818_IRQ_VB_LO_MSK,
36162306a36Sopenharmony_ci		.reg_offset = 0,
36262306a36Sopenharmony_ci	},
36362306a36Sopenharmony_ci	[RK818_IRQ_PWRON] = {
36462306a36Sopenharmony_ci		.mask = RK818_IRQ_PWRON_MSK,
36562306a36Sopenharmony_ci		.reg_offset = 0,
36662306a36Sopenharmony_ci	},
36762306a36Sopenharmony_ci	[RK818_IRQ_PWRON_LP] = {
36862306a36Sopenharmony_ci		.mask = RK818_IRQ_PWRON_LP_MSK,
36962306a36Sopenharmony_ci		.reg_offset = 0,
37062306a36Sopenharmony_ci	},
37162306a36Sopenharmony_ci	[RK818_IRQ_HOTDIE] = {
37262306a36Sopenharmony_ci		.mask = RK818_IRQ_HOTDIE_MSK,
37362306a36Sopenharmony_ci		.reg_offset = 0,
37462306a36Sopenharmony_ci	},
37562306a36Sopenharmony_ci	[RK818_IRQ_RTC_ALARM] = {
37662306a36Sopenharmony_ci		.mask = RK818_IRQ_RTC_ALARM_MSK,
37762306a36Sopenharmony_ci		.reg_offset = 0,
37862306a36Sopenharmony_ci	},
37962306a36Sopenharmony_ci	[RK818_IRQ_RTC_PERIOD] = {
38062306a36Sopenharmony_ci		.mask = RK818_IRQ_RTC_PERIOD_MSK,
38162306a36Sopenharmony_ci		.reg_offset = 0,
38262306a36Sopenharmony_ci	},
38362306a36Sopenharmony_ci	[RK818_IRQ_USB_OV] = {
38462306a36Sopenharmony_ci		.mask = RK818_IRQ_USB_OV_MSK,
38562306a36Sopenharmony_ci		.reg_offset = 0,
38662306a36Sopenharmony_ci	},
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_ci	/* INT_STS2 */
38962306a36Sopenharmony_ci	[RK818_IRQ_PLUG_IN] = {
39062306a36Sopenharmony_ci		.mask = RK818_IRQ_PLUG_IN_MSK,
39162306a36Sopenharmony_ci		.reg_offset = 1,
39262306a36Sopenharmony_ci	},
39362306a36Sopenharmony_ci	[RK818_IRQ_PLUG_OUT] = {
39462306a36Sopenharmony_ci		.mask = RK818_IRQ_PLUG_OUT_MSK,
39562306a36Sopenharmony_ci		.reg_offset = 1,
39662306a36Sopenharmony_ci	},
39762306a36Sopenharmony_ci	[RK818_IRQ_CHG_OK] = {
39862306a36Sopenharmony_ci		.mask = RK818_IRQ_CHG_OK_MSK,
39962306a36Sopenharmony_ci		.reg_offset = 1,
40062306a36Sopenharmony_ci	},
40162306a36Sopenharmony_ci	[RK818_IRQ_CHG_TE] = {
40262306a36Sopenharmony_ci		.mask = RK818_IRQ_CHG_TE_MSK,
40362306a36Sopenharmony_ci		.reg_offset = 1,
40462306a36Sopenharmony_ci	},
40562306a36Sopenharmony_ci	[RK818_IRQ_CHG_TS1] = {
40662306a36Sopenharmony_ci		.mask = RK818_IRQ_CHG_TS1_MSK,
40762306a36Sopenharmony_ci		.reg_offset = 1,
40862306a36Sopenharmony_ci	},
40962306a36Sopenharmony_ci	[RK818_IRQ_TS2] = {
41062306a36Sopenharmony_ci		.mask = RK818_IRQ_TS2_MSK,
41162306a36Sopenharmony_ci		.reg_offset = 1,
41262306a36Sopenharmony_ci	},
41362306a36Sopenharmony_ci	[RK818_IRQ_CHG_CVTLIM] = {
41462306a36Sopenharmony_ci		.mask = RK818_IRQ_CHG_CVTLIM_MSK,
41562306a36Sopenharmony_ci		.reg_offset = 1,
41662306a36Sopenharmony_ci	},
41762306a36Sopenharmony_ci	[RK818_IRQ_DISCHG_ILIM] = {
41862306a36Sopenharmony_ci		.mask = RK818_IRQ_DISCHG_ILIM_MSK,
41962306a36Sopenharmony_ci		.reg_offset = 1,
42062306a36Sopenharmony_ci	},
42162306a36Sopenharmony_ci};
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_cistatic const struct regmap_irq rk817_irqs[RK817_IRQ_END] = {
42462306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(0, 8),
42562306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(1, 8),
42662306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(2, 8),
42762306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(3, 8),
42862306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(4, 8),
42962306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(5, 8),
43062306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(6, 8),
43162306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(7, 8),
43262306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(8, 8),
43362306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(9, 8),
43462306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(10, 8),
43562306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(11, 8),
43662306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(12, 8),
43762306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(13, 8),
43862306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(14, 8),
43962306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(15, 8),
44062306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(16, 8),
44162306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(17, 8),
44262306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(18, 8),
44362306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(19, 8),
44462306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(20, 8),
44562306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(21, 8),
44662306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(22, 8),
44762306a36Sopenharmony_ci	REGMAP_IRQ_REG_LINE(23, 8)
44862306a36Sopenharmony_ci};
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_cistatic struct regmap_irq_chip rk805_irq_chip = {
45162306a36Sopenharmony_ci	.name = "rk805",
45262306a36Sopenharmony_ci	.irqs = rk805_irqs,
45362306a36Sopenharmony_ci	.num_irqs = ARRAY_SIZE(rk805_irqs),
45462306a36Sopenharmony_ci	.num_regs = 1,
45562306a36Sopenharmony_ci	.status_base = RK805_INT_STS_REG,
45662306a36Sopenharmony_ci	.mask_base = RK805_INT_STS_MSK_REG,
45762306a36Sopenharmony_ci	.ack_base = RK805_INT_STS_REG,
45862306a36Sopenharmony_ci	.init_ack_masked = true,
45962306a36Sopenharmony_ci};
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_cistatic struct regmap_irq_chip rk806_irq_chip = {
46262306a36Sopenharmony_ci	.name = "rk806",
46362306a36Sopenharmony_ci	.irqs = rk806_irqs,
46462306a36Sopenharmony_ci	.num_irqs = ARRAY_SIZE(rk806_irqs),
46562306a36Sopenharmony_ci	.num_regs = 2,
46662306a36Sopenharmony_ci	.irq_reg_stride = 2,
46762306a36Sopenharmony_ci	.mask_base = RK806_INT_MSK0,
46862306a36Sopenharmony_ci	.status_base = RK806_INT_STS0,
46962306a36Sopenharmony_ci	.ack_base = RK806_INT_STS0,
47062306a36Sopenharmony_ci	.init_ack_masked = true,
47162306a36Sopenharmony_ci};
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_cistatic const struct regmap_irq_chip rk808_irq_chip = {
47462306a36Sopenharmony_ci	.name = "rk808",
47562306a36Sopenharmony_ci	.irqs = rk808_irqs,
47662306a36Sopenharmony_ci	.num_irqs = ARRAY_SIZE(rk808_irqs),
47762306a36Sopenharmony_ci	.num_regs = 2,
47862306a36Sopenharmony_ci	.irq_reg_stride = 2,
47962306a36Sopenharmony_ci	.status_base = RK808_INT_STS_REG1,
48062306a36Sopenharmony_ci	.mask_base = RK808_INT_STS_MSK_REG1,
48162306a36Sopenharmony_ci	.ack_base = RK808_INT_STS_REG1,
48262306a36Sopenharmony_ci	.init_ack_masked = true,
48362306a36Sopenharmony_ci};
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_cistatic struct regmap_irq_chip rk817_irq_chip = {
48662306a36Sopenharmony_ci	.name = "rk817",
48762306a36Sopenharmony_ci	.irqs = rk817_irqs,
48862306a36Sopenharmony_ci	.num_irqs = ARRAY_SIZE(rk817_irqs),
48962306a36Sopenharmony_ci	.num_regs = 3,
49062306a36Sopenharmony_ci	.irq_reg_stride = 2,
49162306a36Sopenharmony_ci	.status_base = RK817_INT_STS_REG0,
49262306a36Sopenharmony_ci	.mask_base = RK817_INT_STS_MSK_REG0,
49362306a36Sopenharmony_ci	.ack_base = RK817_INT_STS_REG0,
49462306a36Sopenharmony_ci	.init_ack_masked = true,
49562306a36Sopenharmony_ci};
49662306a36Sopenharmony_ci
49762306a36Sopenharmony_cistatic const struct regmap_irq_chip rk818_irq_chip = {
49862306a36Sopenharmony_ci	.name = "rk818",
49962306a36Sopenharmony_ci	.irqs = rk818_irqs,
50062306a36Sopenharmony_ci	.num_irqs = ARRAY_SIZE(rk818_irqs),
50162306a36Sopenharmony_ci	.num_regs = 2,
50262306a36Sopenharmony_ci	.irq_reg_stride = 2,
50362306a36Sopenharmony_ci	.status_base = RK818_INT_STS_REG1,
50462306a36Sopenharmony_ci	.mask_base = RK818_INT_STS_MSK_REG1,
50562306a36Sopenharmony_ci	.ack_base = RK818_INT_STS_REG1,
50662306a36Sopenharmony_ci	.init_ack_masked = true,
50762306a36Sopenharmony_ci};
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_cistatic int rk808_power_off(struct sys_off_data *data)
51062306a36Sopenharmony_ci{
51162306a36Sopenharmony_ci	struct rk808 *rk808 = data->cb_data;
51262306a36Sopenharmony_ci	int ret;
51362306a36Sopenharmony_ci	unsigned int reg, bit;
51462306a36Sopenharmony_ci
51562306a36Sopenharmony_ci	switch (rk808->variant) {
51662306a36Sopenharmony_ci	case RK805_ID:
51762306a36Sopenharmony_ci		reg = RK805_DEV_CTRL_REG;
51862306a36Sopenharmony_ci		bit = DEV_OFF;
51962306a36Sopenharmony_ci		break;
52062306a36Sopenharmony_ci	case RK808_ID:
52162306a36Sopenharmony_ci		reg = RK808_DEVCTRL_REG,
52262306a36Sopenharmony_ci		bit = DEV_OFF_RST;
52362306a36Sopenharmony_ci		break;
52462306a36Sopenharmony_ci	case RK809_ID:
52562306a36Sopenharmony_ci	case RK817_ID:
52662306a36Sopenharmony_ci		reg = RK817_SYS_CFG(3);
52762306a36Sopenharmony_ci		bit = DEV_OFF;
52862306a36Sopenharmony_ci		break;
52962306a36Sopenharmony_ci	case RK818_ID:
53062306a36Sopenharmony_ci		reg = RK818_DEVCTRL_REG;
53162306a36Sopenharmony_ci		bit = DEV_OFF;
53262306a36Sopenharmony_ci		break;
53362306a36Sopenharmony_ci	default:
53462306a36Sopenharmony_ci		return NOTIFY_DONE;
53562306a36Sopenharmony_ci	}
53662306a36Sopenharmony_ci	ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
53762306a36Sopenharmony_ci	if (ret)
53862306a36Sopenharmony_ci		dev_err(rk808->dev, "Failed to shutdown device!\n");
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci	return NOTIFY_DONE;
54162306a36Sopenharmony_ci}
54262306a36Sopenharmony_ci
54362306a36Sopenharmony_cistatic int rk808_restart(struct sys_off_data *data)
54462306a36Sopenharmony_ci{
54562306a36Sopenharmony_ci	struct rk808 *rk808 = data->cb_data;
54662306a36Sopenharmony_ci	unsigned int reg, bit;
54762306a36Sopenharmony_ci	int ret;
54862306a36Sopenharmony_ci
54962306a36Sopenharmony_ci	switch (rk808->variant) {
55062306a36Sopenharmony_ci	case RK809_ID:
55162306a36Sopenharmony_ci	case RK817_ID:
55262306a36Sopenharmony_ci		reg = RK817_SYS_CFG(3);
55362306a36Sopenharmony_ci		bit = DEV_RST;
55462306a36Sopenharmony_ci		break;
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_ci	default:
55762306a36Sopenharmony_ci		return NOTIFY_DONE;
55862306a36Sopenharmony_ci	}
55962306a36Sopenharmony_ci	ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
56062306a36Sopenharmony_ci	if (ret)
56162306a36Sopenharmony_ci		dev_err(rk808->dev, "Failed to restart device!\n");
56262306a36Sopenharmony_ci
56362306a36Sopenharmony_ci	return NOTIFY_DONE;
56462306a36Sopenharmony_ci}
56562306a36Sopenharmony_ci
56662306a36Sopenharmony_civoid rk8xx_shutdown(struct device *dev)
56762306a36Sopenharmony_ci{
56862306a36Sopenharmony_ci	struct rk808 *rk808 = dev_get_drvdata(dev);
56962306a36Sopenharmony_ci	int ret;
57062306a36Sopenharmony_ci
57162306a36Sopenharmony_ci	switch (rk808->variant) {
57262306a36Sopenharmony_ci	case RK805_ID:
57362306a36Sopenharmony_ci		ret = regmap_update_bits(rk808->regmap,
57462306a36Sopenharmony_ci					 RK805_GPIO_IO_POL_REG,
57562306a36Sopenharmony_ci					 SLP_SD_MSK,
57662306a36Sopenharmony_ci					 SHUTDOWN_FUN);
57762306a36Sopenharmony_ci		break;
57862306a36Sopenharmony_ci	case RK809_ID:
57962306a36Sopenharmony_ci	case RK817_ID:
58062306a36Sopenharmony_ci		ret = regmap_update_bits(rk808->regmap,
58162306a36Sopenharmony_ci					 RK817_SYS_CFG(3),
58262306a36Sopenharmony_ci					 RK817_SLPPIN_FUNC_MSK,
58362306a36Sopenharmony_ci					 SLPPIN_DN_FUN);
58462306a36Sopenharmony_ci		break;
58562306a36Sopenharmony_ci	default:
58662306a36Sopenharmony_ci		return;
58762306a36Sopenharmony_ci	}
58862306a36Sopenharmony_ci	if (ret)
58962306a36Sopenharmony_ci		dev_warn(dev,
59062306a36Sopenharmony_ci			 "Cannot switch to power down function\n");
59162306a36Sopenharmony_ci}
59262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rk8xx_shutdown);
59362306a36Sopenharmony_ci
59462306a36Sopenharmony_ciint rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap)
59562306a36Sopenharmony_ci{
59662306a36Sopenharmony_ci	struct rk808 *rk808;
59762306a36Sopenharmony_ci	const struct rk808_reg_data *pre_init_reg;
59862306a36Sopenharmony_ci	const struct mfd_cell *cells;
59962306a36Sopenharmony_ci	int dual_support = 0;
60062306a36Sopenharmony_ci	int nr_pre_init_regs;
60162306a36Sopenharmony_ci	int nr_cells;
60262306a36Sopenharmony_ci	int ret;
60362306a36Sopenharmony_ci	int i;
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_ci	rk808 = devm_kzalloc(dev, sizeof(*rk808), GFP_KERNEL);
60662306a36Sopenharmony_ci	if (!rk808)
60762306a36Sopenharmony_ci		return -ENOMEM;
60862306a36Sopenharmony_ci	rk808->dev = dev;
60962306a36Sopenharmony_ci	rk808->variant = variant;
61062306a36Sopenharmony_ci	rk808->regmap = regmap;
61162306a36Sopenharmony_ci	dev_set_drvdata(dev, rk808);
61262306a36Sopenharmony_ci
61362306a36Sopenharmony_ci	switch (rk808->variant) {
61462306a36Sopenharmony_ci	case RK805_ID:
61562306a36Sopenharmony_ci		rk808->regmap_irq_chip = &rk805_irq_chip;
61662306a36Sopenharmony_ci		pre_init_reg = rk805_pre_init_reg;
61762306a36Sopenharmony_ci		nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg);
61862306a36Sopenharmony_ci		cells = rk805s;
61962306a36Sopenharmony_ci		nr_cells = ARRAY_SIZE(rk805s);
62062306a36Sopenharmony_ci		break;
62162306a36Sopenharmony_ci	case RK806_ID:
62262306a36Sopenharmony_ci		rk808->regmap_irq_chip = &rk806_irq_chip;
62362306a36Sopenharmony_ci		pre_init_reg = rk806_pre_init_reg;
62462306a36Sopenharmony_ci		nr_pre_init_regs = ARRAY_SIZE(rk806_pre_init_reg);
62562306a36Sopenharmony_ci		cells = rk806s;
62662306a36Sopenharmony_ci		nr_cells = ARRAY_SIZE(rk806s);
62762306a36Sopenharmony_ci		dual_support = IRQF_SHARED;
62862306a36Sopenharmony_ci		break;
62962306a36Sopenharmony_ci	case RK808_ID:
63062306a36Sopenharmony_ci		rk808->regmap_irq_chip = &rk808_irq_chip;
63162306a36Sopenharmony_ci		pre_init_reg = rk808_pre_init_reg;
63262306a36Sopenharmony_ci		nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg);
63362306a36Sopenharmony_ci		cells = rk808s;
63462306a36Sopenharmony_ci		nr_cells = ARRAY_SIZE(rk808s);
63562306a36Sopenharmony_ci		break;
63662306a36Sopenharmony_ci	case RK818_ID:
63762306a36Sopenharmony_ci		rk808->regmap_irq_chip = &rk818_irq_chip;
63862306a36Sopenharmony_ci		pre_init_reg = rk818_pre_init_reg;
63962306a36Sopenharmony_ci		nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg);
64062306a36Sopenharmony_ci		cells = rk818s;
64162306a36Sopenharmony_ci		nr_cells = ARRAY_SIZE(rk818s);
64262306a36Sopenharmony_ci		break;
64362306a36Sopenharmony_ci	case RK809_ID:
64462306a36Sopenharmony_ci	case RK817_ID:
64562306a36Sopenharmony_ci		rk808->regmap_irq_chip = &rk817_irq_chip;
64662306a36Sopenharmony_ci		pre_init_reg = rk817_pre_init_reg;
64762306a36Sopenharmony_ci		nr_pre_init_regs = ARRAY_SIZE(rk817_pre_init_reg);
64862306a36Sopenharmony_ci		cells = rk817s;
64962306a36Sopenharmony_ci		nr_cells = ARRAY_SIZE(rk817s);
65062306a36Sopenharmony_ci		break;
65162306a36Sopenharmony_ci	default:
65262306a36Sopenharmony_ci		dev_err(dev, "Unsupported RK8XX ID %lu\n", rk808->variant);
65362306a36Sopenharmony_ci		return -EINVAL;
65462306a36Sopenharmony_ci	}
65562306a36Sopenharmony_ci
65662306a36Sopenharmony_ci	if (!irq)
65762306a36Sopenharmony_ci		return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n");
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_ci	ret = devm_regmap_add_irq_chip(dev, rk808->regmap, irq,
66062306a36Sopenharmony_ci				       IRQF_ONESHOT | dual_support, -1,
66162306a36Sopenharmony_ci				       rk808->regmap_irq_chip, &rk808->irq_data);
66262306a36Sopenharmony_ci	if (ret)
66362306a36Sopenharmony_ci		return dev_err_probe(dev, ret, "Failed to add irq_chip\n");
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_ci	for (i = 0; i < nr_pre_init_regs; i++) {
66662306a36Sopenharmony_ci		ret = regmap_update_bits(rk808->regmap,
66762306a36Sopenharmony_ci					pre_init_reg[i].addr,
66862306a36Sopenharmony_ci					pre_init_reg[i].mask,
66962306a36Sopenharmony_ci					pre_init_reg[i].value);
67062306a36Sopenharmony_ci		if (ret)
67162306a36Sopenharmony_ci			return dev_err_probe(dev, ret, "0x%x write err\n",
67262306a36Sopenharmony_ci					     pre_init_reg[i].addr);
67362306a36Sopenharmony_ci	}
67462306a36Sopenharmony_ci
67562306a36Sopenharmony_ci	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, cells, nr_cells, NULL, 0,
67662306a36Sopenharmony_ci			      regmap_irq_get_domain(rk808->irq_data));
67762306a36Sopenharmony_ci	if (ret)
67862306a36Sopenharmony_ci		return dev_err_probe(dev, ret, "failed to add MFD devices\n");
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_ci	if (device_property_read_bool(dev, "rockchip,system-power-controller")) {
68162306a36Sopenharmony_ci		ret = devm_register_sys_off_handler(dev,
68262306a36Sopenharmony_ci				    SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH,
68362306a36Sopenharmony_ci				    &rk808_power_off, rk808);
68462306a36Sopenharmony_ci		if (ret)
68562306a36Sopenharmony_ci			return dev_err_probe(dev, ret,
68662306a36Sopenharmony_ci					     "failed to register poweroff handler\n");
68762306a36Sopenharmony_ci
68862306a36Sopenharmony_ci		switch (rk808->variant) {
68962306a36Sopenharmony_ci		case RK809_ID:
69062306a36Sopenharmony_ci		case RK817_ID:
69162306a36Sopenharmony_ci			ret = devm_register_sys_off_handler(dev,
69262306a36Sopenharmony_ci							    SYS_OFF_MODE_RESTART, SYS_OFF_PRIO_HIGH,
69362306a36Sopenharmony_ci							    &rk808_restart, rk808);
69462306a36Sopenharmony_ci			if (ret)
69562306a36Sopenharmony_ci				dev_warn(dev, "failed to register rst handler, %d\n", ret);
69662306a36Sopenharmony_ci			break;
69762306a36Sopenharmony_ci		default:
69862306a36Sopenharmony_ci			dev_dbg(dev, "pmic controlled board reset not supported\n");
69962306a36Sopenharmony_ci			break;
70062306a36Sopenharmony_ci		}
70162306a36Sopenharmony_ci	}
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_ci	return 0;
70462306a36Sopenharmony_ci}
70562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rk8xx_probe);
70662306a36Sopenharmony_ci
70762306a36Sopenharmony_ciint rk8xx_suspend(struct device *dev)
70862306a36Sopenharmony_ci{
70962306a36Sopenharmony_ci	struct rk808 *rk808 = dev_get_drvdata(dev);
71062306a36Sopenharmony_ci	int ret = 0;
71162306a36Sopenharmony_ci
71262306a36Sopenharmony_ci	switch (rk808->variant) {
71362306a36Sopenharmony_ci	case RK805_ID:
71462306a36Sopenharmony_ci		ret = regmap_update_bits(rk808->regmap,
71562306a36Sopenharmony_ci					 RK805_GPIO_IO_POL_REG,
71662306a36Sopenharmony_ci					 SLP_SD_MSK,
71762306a36Sopenharmony_ci					 SLEEP_FUN);
71862306a36Sopenharmony_ci		break;
71962306a36Sopenharmony_ci	case RK809_ID:
72062306a36Sopenharmony_ci	case RK817_ID:
72162306a36Sopenharmony_ci		ret = regmap_update_bits(rk808->regmap,
72262306a36Sopenharmony_ci					 RK817_SYS_CFG(3),
72362306a36Sopenharmony_ci					 RK817_SLPPIN_FUNC_MSK,
72462306a36Sopenharmony_ci					 SLPPIN_SLP_FUN);
72562306a36Sopenharmony_ci		break;
72662306a36Sopenharmony_ci	default:
72762306a36Sopenharmony_ci		break;
72862306a36Sopenharmony_ci	}
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_ci	return ret;
73162306a36Sopenharmony_ci}
73262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rk8xx_suspend);
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_ciint rk8xx_resume(struct device *dev)
73562306a36Sopenharmony_ci{
73662306a36Sopenharmony_ci	struct rk808 *rk808 = dev_get_drvdata(dev);
73762306a36Sopenharmony_ci	int ret = 0;
73862306a36Sopenharmony_ci
73962306a36Sopenharmony_ci	switch (rk808->variant) {
74062306a36Sopenharmony_ci	case RK809_ID:
74162306a36Sopenharmony_ci	case RK817_ID:
74262306a36Sopenharmony_ci		ret = regmap_update_bits(rk808->regmap,
74362306a36Sopenharmony_ci					 RK817_SYS_CFG(3),
74462306a36Sopenharmony_ci					 RK817_SLPPIN_FUNC_MSK,
74562306a36Sopenharmony_ci					 SLPPIN_NULL_FUN);
74662306a36Sopenharmony_ci		break;
74762306a36Sopenharmony_ci	default:
74862306a36Sopenharmony_ci		break;
74962306a36Sopenharmony_ci	}
75062306a36Sopenharmony_ci
75162306a36Sopenharmony_ci	return ret;
75262306a36Sopenharmony_ci}
75362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(rk8xx_resume);
75462306a36Sopenharmony_ci
75562306a36Sopenharmony_ciMODULE_LICENSE("GPL");
75662306a36Sopenharmony_ciMODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
75762306a36Sopenharmony_ciMODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
75862306a36Sopenharmony_ciMODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
75962306a36Sopenharmony_ciMODULE_DESCRIPTION("RK8xx PMIC core");
760