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