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