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");