cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rk808.c (22821B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * MFD core driver for Rockchip RK808/RK818
      4 *
      5 * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
      6 *
      7 * Author: Chris Zhong <zyw@rock-chips.com>
      8 * Author: Zhang Qing <zhangqing@rock-chips.com>
      9 *
     10 * Copyright (C) 2016 PHYTEC Messtechnik GmbH
     11 *
     12 * Author: Wadim Egorov <w.egorov@phytec.de>
     13 */
     14
     15#include <linux/i2c.h>
     16#include <linux/interrupt.h>
     17#include <linux/mfd/rk808.h>
     18#include <linux/mfd/core.h>
     19#include <linux/module.h>
     20#include <linux/of_device.h>
     21#include <linux/regmap.h>
     22#include <linux/reboot.h>
     23
     24struct rk808_reg_data {
     25	int addr;
     26	int mask;
     27	int value;
     28};
     29
     30static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
     31{
     32	/*
     33	 * Notes:
     34	 * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
     35	 *   we don't use that feature.  It's better to cache.
     36	 * - It's unlikely we care that RK808_DEVCTRL_REG is volatile since
     37	 *   bits are cleared in case when we shutoff anyway, but better safe.
     38	 */
     39
     40	switch (reg) {
     41	case RK808_SECONDS_REG ... RK808_WEEKS_REG:
     42	case RK808_RTC_STATUS_REG:
     43	case RK808_VB_MON_REG:
     44	case RK808_THERMAL_REG:
     45	case RK808_DCDC_UV_STS_REG:
     46	case RK808_LDO_UV_STS_REG:
     47	case RK808_DCDC_PG_REG:
     48	case RK808_LDO_PG_REG:
     49	case RK808_DEVCTRL_REG:
     50	case RK808_INT_STS_REG1:
     51	case RK808_INT_STS_REG2:
     52		return true;
     53	}
     54
     55	return false;
     56}
     57
     58static bool rk817_is_volatile_reg(struct device *dev, unsigned int reg)
     59{
     60	/*
     61	 * Notes:
     62	 * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
     63	 *   we don't use that feature.  It's better to cache.
     64	 */
     65
     66	switch (reg) {
     67	case RK817_SECONDS_REG ... RK817_WEEKS_REG:
     68	case RK817_RTC_STATUS_REG:
     69	case RK817_CODEC_DTOP_LPT_SRST:
     70	case RK817_INT_STS_REG0:
     71	case RK817_INT_STS_REG1:
     72	case RK817_INT_STS_REG2:
     73	case RK817_SYS_STS:
     74		return true;
     75	}
     76
     77	return true;
     78}
     79
     80static const struct regmap_config rk818_regmap_config = {
     81	.reg_bits = 8,
     82	.val_bits = 8,
     83	.max_register = RK818_USB_CTRL_REG,
     84	.cache_type = REGCACHE_RBTREE,
     85	.volatile_reg = rk808_is_volatile_reg,
     86};
     87
     88static const struct regmap_config rk805_regmap_config = {
     89	.reg_bits = 8,
     90	.val_bits = 8,
     91	.max_register = RK805_OFF_SOURCE_REG,
     92	.cache_type = REGCACHE_RBTREE,
     93	.volatile_reg = rk808_is_volatile_reg,
     94};
     95
     96static const struct regmap_config rk808_regmap_config = {
     97	.reg_bits = 8,
     98	.val_bits = 8,
     99	.max_register = RK808_IO_POL_REG,
    100	.cache_type = REGCACHE_RBTREE,
    101	.volatile_reg = rk808_is_volatile_reg,
    102};
    103
    104static const struct regmap_config rk817_regmap_config = {
    105	.reg_bits = 8,
    106	.val_bits = 8,
    107	.max_register = RK817_GPIO_INT_CFG,
    108	.cache_type = REGCACHE_NONE,
    109	.volatile_reg = rk817_is_volatile_reg,
    110};
    111
    112static const struct resource rtc_resources[] = {
    113	DEFINE_RES_IRQ(RK808_IRQ_RTC_ALARM),
    114};
    115
    116static const struct resource rk817_rtc_resources[] = {
    117	DEFINE_RES_IRQ(RK817_IRQ_RTC_ALARM),
    118};
    119
    120static const struct resource rk805_key_resources[] = {
    121	DEFINE_RES_IRQ(RK805_IRQ_PWRON_RISE),
    122	DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL),
    123};
    124
    125static const struct resource rk817_pwrkey_resources[] = {
    126	DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE),
    127	DEFINE_RES_IRQ(RK817_IRQ_PWRON_FALL),
    128};
    129
    130static const struct mfd_cell rk805s[] = {
    131	{ .name = "rk808-clkout", },
    132	{ .name = "rk808-regulator", },
    133	{ .name = "rk805-pinctrl", },
    134	{
    135		.name = "rk808-rtc",
    136		.num_resources = ARRAY_SIZE(rtc_resources),
    137		.resources = &rtc_resources[0],
    138	},
    139	{	.name = "rk805-pwrkey",
    140		.num_resources = ARRAY_SIZE(rk805_key_resources),
    141		.resources = &rk805_key_resources[0],
    142	},
    143};
    144
    145static const struct mfd_cell rk808s[] = {
    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
    155static const struct mfd_cell rk817s[] = {
    156	{ .name = "rk808-clkout",},
    157	{ .name = "rk808-regulator",},
    158	{
    159		.name = "rk805-pwrkey",
    160		.num_resources = ARRAY_SIZE(rk817_pwrkey_resources),
    161		.resources = &rk817_pwrkey_resources[0],
    162	},
    163	{
    164		.name = "rk808-rtc",
    165		.num_resources = ARRAY_SIZE(rk817_rtc_resources),
    166		.resources = &rk817_rtc_resources[0],
    167	},
    168	{ .name = "rk817-codec",},
    169};
    170
    171static const struct mfd_cell rk818s[] = {
    172	{ .name = "rk808-clkout", },
    173	{ .name = "rk808-regulator", },
    174	{
    175		.name = "rk808-rtc",
    176		.num_resources = ARRAY_SIZE(rtc_resources),
    177		.resources = rtc_resources,
    178	},
    179};
    180
    181static const struct rk808_reg_data rk805_pre_init_reg[] = {
    182	{RK805_BUCK1_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
    183				 RK805_BUCK1_2_ILMAX_4000MA},
    184	{RK805_BUCK2_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
    185				 RK805_BUCK1_2_ILMAX_4000MA},
    186	{RK805_BUCK3_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK,
    187				 RK805_BUCK3_ILMAX_3000MA},
    188	{RK805_BUCK4_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK,
    189				 RK805_BUCK4_ILMAX_3500MA},
    190	{RK805_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_400MA},
    191	{RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C},
    192};
    193
    194static const struct rk808_reg_data rk808_pre_init_reg[] = {
    195	{ RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_150MA },
    196	{ RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_200MA },
    197	{ RK808_BOOST_CONFIG_REG, BOOST_ILMIN_MASK, BOOST_ILMIN_100MA },
    198	{ RK808_BUCK1_CONFIG_REG, BUCK1_RATE_MASK,  BUCK_ILMIN_200MA },
    199	{ RK808_BUCK2_CONFIG_REG, BUCK2_RATE_MASK,  BUCK_ILMIN_200MA },
    200	{ RK808_DCDC_UV_ACT_REG,  BUCK_UV_ACT_MASK, BUCK_UV_ACT_DISABLE},
    201	{ RK808_VB_MON_REG,       MASK_ALL,         VB_LO_ACT |
    202						    VB_LO_SEL_3500MV },
    203};
    204
    205static 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
    291static 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
    309static const struct regmap_irq rk805_irqs[] = {
    310	[RK805_IRQ_PWRON_RISE] = {
    311		.mask = RK805_IRQ_PWRON_RISE_MSK,
    312		.reg_offset = 0,
    313	},
    314	[RK805_IRQ_VB_LOW] = {
    315		.mask = RK805_IRQ_VB_LOW_MSK,
    316		.reg_offset = 0,
    317	},
    318	[RK805_IRQ_PWRON] = {
    319		.mask = RK805_IRQ_PWRON_MSK,
    320		.reg_offset = 0,
    321	},
    322	[RK805_IRQ_PWRON_LP] = {
    323		.mask = RK805_IRQ_PWRON_LP_MSK,
    324		.reg_offset = 0,
    325	},
    326	[RK805_IRQ_HOTDIE] = {
    327		.mask = RK805_IRQ_HOTDIE_MSK,
    328		.reg_offset = 0,
    329	},
    330	[RK805_IRQ_RTC_ALARM] = {
    331		.mask = RK805_IRQ_RTC_ALARM_MSK,
    332		.reg_offset = 0,
    333	},
    334	[RK805_IRQ_RTC_PERIOD] = {
    335		.mask = RK805_IRQ_RTC_PERIOD_MSK,
    336		.reg_offset = 0,
    337	},
    338	[RK805_IRQ_PWRON_FALL] = {
    339		.mask = RK805_IRQ_PWRON_FALL_MSK,
    340		.reg_offset = 0,
    341	},
    342};
    343
    344static const struct regmap_irq rk808_irqs[] = {
    345	/* INT_STS */
    346	[RK808_IRQ_VOUT_LO] = {
    347		.mask = RK808_IRQ_VOUT_LO_MSK,
    348		.reg_offset = 0,
    349	},
    350	[RK808_IRQ_VB_LO] = {
    351		.mask = RK808_IRQ_VB_LO_MSK,
    352		.reg_offset = 0,
    353	},
    354	[RK808_IRQ_PWRON] = {
    355		.mask = RK808_IRQ_PWRON_MSK,
    356		.reg_offset = 0,
    357	},
    358	[RK808_IRQ_PWRON_LP] = {
    359		.mask = RK808_IRQ_PWRON_LP_MSK,
    360		.reg_offset = 0,
    361	},
    362	[RK808_IRQ_HOTDIE] = {
    363		.mask = RK808_IRQ_HOTDIE_MSK,
    364		.reg_offset = 0,
    365	},
    366	[RK808_IRQ_RTC_ALARM] = {
    367		.mask = RK808_IRQ_RTC_ALARM_MSK,
    368		.reg_offset = 0,
    369	},
    370	[RK808_IRQ_RTC_PERIOD] = {
    371		.mask = RK808_IRQ_RTC_PERIOD_MSK,
    372		.reg_offset = 0,
    373	},
    374
    375	/* INT_STS2 */
    376	[RK808_IRQ_PLUG_IN_INT] = {
    377		.mask = RK808_IRQ_PLUG_IN_INT_MSK,
    378		.reg_offset = 1,
    379	},
    380	[RK808_IRQ_PLUG_OUT_INT] = {
    381		.mask = RK808_IRQ_PLUG_OUT_INT_MSK,
    382		.reg_offset = 1,
    383	},
    384};
    385
    386static const struct regmap_irq rk818_irqs[] = {
    387	/* INT_STS */
    388	[RK818_IRQ_VOUT_LO] = {
    389		.mask = RK818_IRQ_VOUT_LO_MSK,
    390		.reg_offset = 0,
    391	},
    392	[RK818_IRQ_VB_LO] = {
    393		.mask = RK818_IRQ_VB_LO_MSK,
    394		.reg_offset = 0,
    395	},
    396	[RK818_IRQ_PWRON] = {
    397		.mask = RK818_IRQ_PWRON_MSK,
    398		.reg_offset = 0,
    399	},
    400	[RK818_IRQ_PWRON_LP] = {
    401		.mask = RK818_IRQ_PWRON_LP_MSK,
    402		.reg_offset = 0,
    403	},
    404	[RK818_IRQ_HOTDIE] = {
    405		.mask = RK818_IRQ_HOTDIE_MSK,
    406		.reg_offset = 0,
    407	},
    408	[RK818_IRQ_RTC_ALARM] = {
    409		.mask = RK818_IRQ_RTC_ALARM_MSK,
    410		.reg_offset = 0,
    411	},
    412	[RK818_IRQ_RTC_PERIOD] = {
    413		.mask = RK818_IRQ_RTC_PERIOD_MSK,
    414		.reg_offset = 0,
    415	},
    416	[RK818_IRQ_USB_OV] = {
    417		.mask = RK818_IRQ_USB_OV_MSK,
    418		.reg_offset = 0,
    419	},
    420
    421	/* INT_STS2 */
    422	[RK818_IRQ_PLUG_IN] = {
    423		.mask = RK818_IRQ_PLUG_IN_MSK,
    424		.reg_offset = 1,
    425	},
    426	[RK818_IRQ_PLUG_OUT] = {
    427		.mask = RK818_IRQ_PLUG_OUT_MSK,
    428		.reg_offset = 1,
    429	},
    430	[RK818_IRQ_CHG_OK] = {
    431		.mask = RK818_IRQ_CHG_OK_MSK,
    432		.reg_offset = 1,
    433	},
    434	[RK818_IRQ_CHG_TE] = {
    435		.mask = RK818_IRQ_CHG_TE_MSK,
    436		.reg_offset = 1,
    437	},
    438	[RK818_IRQ_CHG_TS1] = {
    439		.mask = RK818_IRQ_CHG_TS1_MSK,
    440		.reg_offset = 1,
    441	},
    442	[RK818_IRQ_TS2] = {
    443		.mask = RK818_IRQ_TS2_MSK,
    444		.reg_offset = 1,
    445	},
    446	[RK818_IRQ_CHG_CVTLIM] = {
    447		.mask = RK818_IRQ_CHG_CVTLIM_MSK,
    448		.reg_offset = 1,
    449	},
    450	[RK818_IRQ_DISCHG_ILIM] = {
    451		.mask = RK818_IRQ_DISCHG_ILIM_MSK,
    452		.reg_offset = 1,
    453	},
    454};
    455
    456static const struct regmap_irq rk817_irqs[RK817_IRQ_END] = {
    457	REGMAP_IRQ_REG_LINE(0, 8),
    458	REGMAP_IRQ_REG_LINE(1, 8),
    459	REGMAP_IRQ_REG_LINE(2, 8),
    460	REGMAP_IRQ_REG_LINE(3, 8),
    461	REGMAP_IRQ_REG_LINE(4, 8),
    462	REGMAP_IRQ_REG_LINE(5, 8),
    463	REGMAP_IRQ_REG_LINE(6, 8),
    464	REGMAP_IRQ_REG_LINE(7, 8),
    465	REGMAP_IRQ_REG_LINE(8, 8),
    466	REGMAP_IRQ_REG_LINE(9, 8),
    467	REGMAP_IRQ_REG_LINE(10, 8),
    468	REGMAP_IRQ_REG_LINE(11, 8),
    469	REGMAP_IRQ_REG_LINE(12, 8),
    470	REGMAP_IRQ_REG_LINE(13, 8),
    471	REGMAP_IRQ_REG_LINE(14, 8),
    472	REGMAP_IRQ_REG_LINE(15, 8),
    473	REGMAP_IRQ_REG_LINE(16, 8),
    474	REGMAP_IRQ_REG_LINE(17, 8),
    475	REGMAP_IRQ_REG_LINE(18, 8),
    476	REGMAP_IRQ_REG_LINE(19, 8),
    477	REGMAP_IRQ_REG_LINE(20, 8),
    478	REGMAP_IRQ_REG_LINE(21, 8),
    479	REGMAP_IRQ_REG_LINE(22, 8),
    480	REGMAP_IRQ_REG_LINE(23, 8)
    481};
    482
    483static struct regmap_irq_chip rk805_irq_chip = {
    484	.name = "rk805",
    485	.irqs = rk805_irqs,
    486	.num_irqs = ARRAY_SIZE(rk805_irqs),
    487	.num_regs = 1,
    488	.status_base = RK805_INT_STS_REG,
    489	.mask_base = RK805_INT_STS_MSK_REG,
    490	.ack_base = RK805_INT_STS_REG,
    491	.init_ack_masked = true,
    492};
    493
    494static const struct regmap_irq_chip rk808_irq_chip = {
    495	.name = "rk808",
    496	.irqs = rk808_irqs,
    497	.num_irqs = ARRAY_SIZE(rk808_irqs),
    498	.num_regs = 2,
    499	.irq_reg_stride = 2,
    500	.status_base = RK808_INT_STS_REG1,
    501	.mask_base = RK808_INT_STS_MSK_REG1,
    502	.ack_base = RK808_INT_STS_REG1,
    503	.init_ack_masked = true,
    504};
    505
    506static struct regmap_irq_chip rk817_irq_chip = {
    507	.name = "rk817",
    508	.irqs = rk817_irqs,
    509	.num_irqs = ARRAY_SIZE(rk817_irqs),
    510	.num_regs = 3,
    511	.irq_reg_stride = 2,
    512	.status_base = RK817_INT_STS_REG0,
    513	.mask_base = RK817_INT_STS_MSK_REG0,
    514	.ack_base = RK817_INT_STS_REG0,
    515	.init_ack_masked = true,
    516};
    517
    518static const struct regmap_irq_chip rk818_irq_chip = {
    519	.name = "rk818",
    520	.irqs = rk818_irqs,
    521	.num_irqs = ARRAY_SIZE(rk818_irqs),
    522	.num_regs = 2,
    523	.irq_reg_stride = 2,
    524	.status_base = RK818_INT_STS_REG1,
    525	.mask_base = RK818_INT_STS_MSK_REG1,
    526	.ack_base = RK818_INT_STS_REG1,
    527	.init_ack_masked = true,
    528};
    529
    530static struct i2c_client *rk808_i2c_client;
    531
    532static void rk808_pm_power_off(void)
    533{
    534	int ret;
    535	unsigned int reg, bit;
    536	struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
    537
    538	switch (rk808->variant) {
    539	case RK805_ID:
    540		reg = RK805_DEV_CTRL_REG;
    541		bit = DEV_OFF;
    542		break;
    543	case RK808_ID:
    544		reg = RK808_DEVCTRL_REG,
    545		bit = DEV_OFF_RST;
    546		break;
    547	case RK809_ID:
    548	case RK817_ID:
    549		reg = RK817_SYS_CFG(3);
    550		bit = DEV_OFF;
    551		break;
    552	case RK818_ID:
    553		reg = RK818_DEVCTRL_REG;
    554		bit = DEV_OFF;
    555		break;
    556	default:
    557		return;
    558	}
    559	ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
    560	if (ret)
    561		dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n");
    562}
    563
    564static int rk808_restart_notify(struct notifier_block *this, unsigned long mode, void *cmd)
    565{
    566	struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
    567	unsigned int reg, bit;
    568	int ret;
    569
    570	switch (rk808->variant) {
    571	case RK809_ID:
    572	case RK817_ID:
    573		reg = RK817_SYS_CFG(3);
    574		bit = DEV_RST;
    575		break;
    576
    577	default:
    578		return NOTIFY_DONE;
    579	}
    580	ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
    581	if (ret)
    582		dev_err(&rk808_i2c_client->dev, "Failed to restart device!\n");
    583
    584	return NOTIFY_DONE;
    585}
    586
    587static struct notifier_block rk808_restart_handler = {
    588	.notifier_call = rk808_restart_notify,
    589	.priority = 192,
    590};
    591
    592static void rk8xx_shutdown(struct i2c_client *client)
    593{
    594	struct rk808 *rk808 = i2c_get_clientdata(client);
    595	int ret;
    596
    597	switch (rk808->variant) {
    598	case RK805_ID:
    599		ret = regmap_update_bits(rk808->regmap,
    600					 RK805_GPIO_IO_POL_REG,
    601					 SLP_SD_MSK,
    602					 SHUTDOWN_FUN);
    603		break;
    604	case RK809_ID:
    605	case RK817_ID:
    606		ret = regmap_update_bits(rk808->regmap,
    607					 RK817_SYS_CFG(3),
    608					 RK817_SLPPIN_FUNC_MSK,
    609					 SLPPIN_DN_FUN);
    610		break;
    611	default:
    612		return;
    613	}
    614	if (ret)
    615		dev_warn(&client->dev,
    616			 "Cannot switch to power down function\n");
    617}
    618
    619static const struct of_device_id rk808_of_match[] = {
    620	{ .compatible = "rockchip,rk805" },
    621	{ .compatible = "rockchip,rk808" },
    622	{ .compatible = "rockchip,rk809" },
    623	{ .compatible = "rockchip,rk817" },
    624	{ .compatible = "rockchip,rk818" },
    625	{ },
    626};
    627MODULE_DEVICE_TABLE(of, rk808_of_match);
    628
    629static int rk808_probe(struct i2c_client *client,
    630		       const struct i2c_device_id *id)
    631{
    632	struct device_node *np = client->dev.of_node;
    633	struct rk808 *rk808;
    634	const struct rk808_reg_data *pre_init_reg;
    635	const struct mfd_cell *cells;
    636	int nr_pre_init_regs;
    637	int nr_cells;
    638	int msb, lsb;
    639	unsigned char pmic_id_msb, pmic_id_lsb;
    640	int ret;
    641	int i;
    642
    643	rk808 = devm_kzalloc(&client->dev, sizeof(*rk808), GFP_KERNEL);
    644	if (!rk808)
    645		return -ENOMEM;
    646
    647	if (of_device_is_compatible(np, "rockchip,rk817") ||
    648	    of_device_is_compatible(np, "rockchip,rk809")) {
    649		pmic_id_msb = RK817_ID_MSB;
    650		pmic_id_lsb = RK817_ID_LSB;
    651	} else {
    652		pmic_id_msb = RK808_ID_MSB;
    653		pmic_id_lsb = RK808_ID_LSB;
    654	}
    655
    656	/* Read chip variant */
    657	msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
    658	if (msb < 0) {
    659		dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
    660			RK808_ID_MSB);
    661		return msb;
    662	}
    663
    664	lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
    665	if (lsb < 0) {
    666		dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
    667			RK808_ID_LSB);
    668		return lsb;
    669	}
    670
    671	rk808->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
    672	dev_info(&client->dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
    673
    674	switch (rk808->variant) {
    675	case RK805_ID:
    676		rk808->regmap_cfg = &rk805_regmap_config;
    677		rk808->regmap_irq_chip = &rk805_irq_chip;
    678		pre_init_reg = rk805_pre_init_reg;
    679		nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg);
    680		cells = rk805s;
    681		nr_cells = ARRAY_SIZE(rk805s);
    682		break;
    683	case RK808_ID:
    684		rk808->regmap_cfg = &rk808_regmap_config;
    685		rk808->regmap_irq_chip = &rk808_irq_chip;
    686		pre_init_reg = rk808_pre_init_reg;
    687		nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg);
    688		cells = rk808s;
    689		nr_cells = ARRAY_SIZE(rk808s);
    690		break;
    691	case RK818_ID:
    692		rk808->regmap_cfg = &rk818_regmap_config;
    693		rk808->regmap_irq_chip = &rk818_irq_chip;
    694		pre_init_reg = rk818_pre_init_reg;
    695		nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg);
    696		cells = rk818s;
    697		nr_cells = ARRAY_SIZE(rk818s);
    698		break;
    699	case RK809_ID:
    700	case RK817_ID:
    701		rk808->regmap_cfg = &rk817_regmap_config;
    702		rk808->regmap_irq_chip = &rk817_irq_chip;
    703		pre_init_reg = rk817_pre_init_reg;
    704		nr_pre_init_regs = ARRAY_SIZE(rk817_pre_init_reg);
    705		cells = rk817s;
    706		nr_cells = ARRAY_SIZE(rk817s);
    707		break;
    708	default:
    709		dev_err(&client->dev, "Unsupported RK8XX ID %lu\n",
    710			rk808->variant);
    711		return -EINVAL;
    712	}
    713
    714	rk808->i2c = client;
    715	i2c_set_clientdata(client, rk808);
    716
    717	rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg);
    718	if (IS_ERR(rk808->regmap)) {
    719		dev_err(&client->dev, "regmap initialization failed\n");
    720		return PTR_ERR(rk808->regmap);
    721	}
    722
    723	if (!client->irq) {
    724		dev_err(&client->dev, "No interrupt support, no core IRQ\n");
    725		return -EINVAL;
    726	}
    727
    728	ret = regmap_add_irq_chip(rk808->regmap, client->irq,
    729				  IRQF_ONESHOT, -1,
    730				  rk808->regmap_irq_chip, &rk808->irq_data);
    731	if (ret) {
    732		dev_err(&client->dev, "Failed to add irq_chip %d\n", ret);
    733		return ret;
    734	}
    735
    736	for (i = 0; i < nr_pre_init_regs; i++) {
    737		ret = regmap_update_bits(rk808->regmap,
    738					pre_init_reg[i].addr,
    739					pre_init_reg[i].mask,
    740					pre_init_reg[i].value);
    741		if (ret) {
    742			dev_err(&client->dev,
    743				"0x%x write err\n",
    744				pre_init_reg[i].addr);
    745			return ret;
    746		}
    747	}
    748
    749	ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
    750			      cells, nr_cells, NULL, 0,
    751			      regmap_irq_get_domain(rk808->irq_data));
    752	if (ret) {
    753		dev_err(&client->dev, "failed to add MFD devices %d\n", ret);
    754		goto err_irq;
    755	}
    756
    757	if (of_property_read_bool(np, "rockchip,system-power-controller")) {
    758		rk808_i2c_client = client;
    759		pm_power_off = rk808_pm_power_off;
    760
    761		switch (rk808->variant) {
    762		case RK809_ID:
    763		case RK817_ID:
    764			ret = register_restart_handler(&rk808_restart_handler);
    765			if (ret)
    766				dev_warn(&client->dev, "failed to register rst handler, %d\n", ret);
    767			break;
    768		default:
    769			dev_dbg(&client->dev, "pmic controlled board reset not supported\n");
    770			break;
    771		}
    772	}
    773
    774	return 0;
    775
    776err_irq:
    777	regmap_del_irq_chip(client->irq, rk808->irq_data);
    778	return ret;
    779}
    780
    781static int rk808_remove(struct i2c_client *client)
    782{
    783	struct rk808 *rk808 = i2c_get_clientdata(client);
    784
    785	regmap_del_irq_chip(client->irq, rk808->irq_data);
    786
    787	/**
    788	 * pm_power_off may points to a function from another module.
    789	 * Check if the pointer is set by us and only then overwrite it.
    790	 */
    791	if (pm_power_off == rk808_pm_power_off)
    792		pm_power_off = NULL;
    793
    794	unregister_restart_handler(&rk808_restart_handler);
    795
    796	return 0;
    797}
    798
    799static int __maybe_unused rk8xx_suspend(struct device *dev)
    800{
    801	struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev));
    802	int ret = 0;
    803
    804	switch (rk808->variant) {
    805	case RK805_ID:
    806		ret = regmap_update_bits(rk808->regmap,
    807					 RK805_GPIO_IO_POL_REG,
    808					 SLP_SD_MSK,
    809					 SLEEP_FUN);
    810		break;
    811	case RK809_ID:
    812	case RK817_ID:
    813		ret = regmap_update_bits(rk808->regmap,
    814					 RK817_SYS_CFG(3),
    815					 RK817_SLPPIN_FUNC_MSK,
    816					 SLPPIN_SLP_FUN);
    817		break;
    818	default:
    819		break;
    820	}
    821
    822	return ret;
    823}
    824
    825static int __maybe_unused rk8xx_resume(struct device *dev)
    826{
    827	struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev));
    828	int ret = 0;
    829
    830	switch (rk808->variant) {
    831	case RK809_ID:
    832	case RK817_ID:
    833		ret = regmap_update_bits(rk808->regmap,
    834					 RK817_SYS_CFG(3),
    835					 RK817_SLPPIN_FUNC_MSK,
    836					 SLPPIN_NULL_FUN);
    837		break;
    838	default:
    839		break;
    840	}
    841
    842	return ret;
    843}
    844static SIMPLE_DEV_PM_OPS(rk8xx_pm_ops, rk8xx_suspend, rk8xx_resume);
    845
    846static struct i2c_driver rk808_i2c_driver = {
    847	.driver = {
    848		.name = "rk808",
    849		.of_match_table = rk808_of_match,
    850		.pm = &rk8xx_pm_ops,
    851	},
    852	.probe    = rk808_probe,
    853	.remove   = rk808_remove,
    854	.shutdown = rk8xx_shutdown,
    855};
    856
    857module_i2c_driver(rk808_i2c_driver);
    858
    859MODULE_LICENSE("GPL");
    860MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
    861MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
    862MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
    863MODULE_DESCRIPTION("RK808/RK818 PMIC driver");