brintos

brintos / linux-shallow public Read only

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