1 /* 2 * Copyright (C) 2015 Google, Inc 3 * Written by Simon Glass <sjg@chromium.org> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <dm.h> 10 #include <errno.h> 11 #include <irq-generic.h> 12 #include <power/rk8xx_pmic.h> 13 #include <power/pmic.h> 14 15 DECLARE_GLOBAL_DATA_PTR; 16 17 #if defined(CONFIG_IRQ) && !defined(CONFIG_SPL_BUILD) 18 /* RK805 */ 19 static const struct virq_reg rk805_irqs[] = { 20 [RK8XX_IRQ_PWRON_FALL] = { 21 .mask = RK805_IRQ_PWRON_FALL_MSK, 22 .reg_offset = 0, 23 }, 24 [RK8XX_IRQ_PWRON_RISE] = { 25 .mask = RK805_IRQ_PWRON_RISE_MSK, 26 .reg_offset = 0, 27 }, 28 }; 29 30 static struct virq_chip rk805_irq_chip = { 31 .status_base = RK805_INT_STS_REG, 32 .mask_base = RK805_INT_MSK_REG, 33 .num_regs = 1, 34 .i2c_read = pmic_reg_read, 35 .i2c_write = pmic_reg_write, 36 .irqs = rk805_irqs, 37 .num_irqs = ARRAY_SIZE(rk805_irqs), 38 }; 39 40 /* RK808 */ 41 static const struct virq_reg rk808_irqs[] = { 42 [RK8XX_IRQ_PLUG_OUT] = { 43 .mask = RK808_IRQ_PLUG_OUT_MSK, 44 .reg_offset = 1, 45 }, 46 }; 47 48 static struct virq_chip rk808_irq_chip = { 49 .status_base = RK808_INT_STS_REG1, 50 .mask_base = RK808_INT_MSK_REG1, 51 .irq_reg_stride = 2, 52 .num_regs = 2, 53 .i2c_read = pmic_reg_read, 54 .i2c_write = pmic_reg_write, 55 .irqs = rk808_irqs, 56 .num_irqs = ARRAY_SIZE(rk808_irqs), 57 }; 58 59 /* RK816 */ 60 static const struct virq_reg rk816_irqs[] = { 61 [RK8XX_IRQ_PWRON_FALL] = { 62 .mask = RK816_IRQ_PWRON_FALL_MSK, 63 .reg_offset = 0, 64 }, 65 [RK8XX_IRQ_PWRON_RISE] = { 66 .mask = RK816_IRQ_PWRON_RISE_MSK, 67 .reg_offset = 0, 68 }, 69 [RK8XX_IRQ_PLUG_OUT] = { 70 .mask = RK816_IRQ_PLUG_OUT_MSK, 71 .reg_offset = 2, 72 }, 73 [RK8XX_IRQ_CHG_OK] = { 74 .mask = RK816_IRQ_CHR_OK_MSK, 75 .reg_offset = 2, 76 }, 77 }; 78 79 static struct virq_chip rk816_irq_chip = { 80 .status_base = RK816_INT_STS_REG1, 81 .mask_base = RK816_INT_MSK_REG1, 82 .irq_unalign_reg_idx = 1, /* idx <= 1, stride = 3 */ 83 .irq_unalign_reg_stride = 3, 84 .irq_reg_stride = 2, /* idx > 1, stride = 2 */ 85 .num_regs = 3, 86 .i2c_read = pmic_reg_read, 87 .i2c_write = pmic_reg_write, 88 .irqs = rk816_irqs, 89 .num_irqs = ARRAY_SIZE(rk816_irqs), 90 }; 91 92 /* RK818 */ 93 static const struct virq_reg rk818_irqs[] = { 94 [RK8XX_IRQ_PLUG_OUT] = { 95 .mask = RK818_IRQ_PLUG_OUT_MSK, 96 .reg_offset = 1, 97 }, 98 [RK8XX_IRQ_CHG_OK] = { 99 .mask = RK818_IRQ_CHR_OK_MSK, 100 .reg_offset = 1, 101 }, 102 }; 103 104 static struct virq_chip rk818_irq_chip = { 105 .status_base = RK818_INT_STS_REG1, 106 .mask_base = RK818_INT_MSK_REG1, 107 .irq_reg_stride = 2, 108 .num_regs = 2, 109 .i2c_read = pmic_reg_read, 110 .i2c_write = pmic_reg_write, 111 .irqs = rk818_irqs, 112 .num_irqs = ARRAY_SIZE(rk818_irqs), 113 }; 114 115 /* RK817/RK809 */ 116 static const struct virq_reg rk817_irqs[] = { 117 [RK8XX_IRQ_PWRON_FALL] = { 118 .mask = RK817_IRQ_PWRON_FALL_MSK, 119 .reg_offset = 0, 120 }, 121 [RK8XX_IRQ_PWRON_RISE] = { 122 .mask = RK817_IRQ_PWRON_RISE_MSK, 123 .reg_offset = 0, 124 }, 125 [RK8XX_IRQ_PLUG_OUT] = { 126 .mask = RK817_IRQ_PLUG_OUT_MSK, 127 .reg_offset = 1, 128 }, 129 [RK8XX_IRQ_PLUG_IN] = { 130 .mask = RK817_IRQ_PLUG_IN_MSK, 131 .reg_offset = 1, 132 }, 133 }; 134 135 static struct virq_chip rk817_irq_chip = { 136 .status_base = RK817_INT_STS_REG0, 137 .mask_base = RK817_INT_MSK_REG0, 138 .irq_reg_stride = 2, 139 .num_regs = 3, 140 .i2c_read = pmic_reg_read, 141 .i2c_write = pmic_reg_write, 142 .irqs = rk817_irqs, 143 .num_irqs = ARRAY_SIZE(rk817_irqs), 144 }; 145 #endif 146 147 static struct reg_data rk817_init_reg[] = { 148 /* enable the under-voltage protection, 149 * the under-voltage protection will shutdown the LDO3 and reset the PMIC 150 */ 151 { RK817_BUCK4_CMIN, 0x60, 0x60}, 152 /* 153 * Only when system suspend while U-Boot charge needs this config support 154 */ 155 #ifdef CONFIG_DM_CHARGE_DISPLAY 156 /* Set pmic_sleep as sleep function */ 157 { RK817_PMIC_SYS_CFG3, 0x08, 0x18 }, 158 /* Set pmic_int active low */ 159 { RK817_GPIO_INT_CFG, 0x00, 0x02 }, 160 #endif 161 }; 162 163 static struct reg_data rk818_init_current[] = { 164 { REG_USB_CTRL, 0x07, 0x0f}, /* 2A */ 165 }; 166 167 static const struct pmic_child_info pmic_children_info[] = { 168 { .prefix = "DCDC", .driver = "rk8xx_buck"}, 169 { .prefix = "LDO", .driver = "rk8xx_ldo"}, 170 { .prefix = "SWITCH", .driver = "rk8xx_switch"}, 171 { }, 172 }; 173 174 static const struct pmic_child_info power_key_info[] = { 175 { .prefix = "pwrkey", .driver = "rk8xx_pwrkey"}, 176 { }, 177 }; 178 179 static const struct pmic_child_info rtc_info[] = { 180 { .prefix = "rtc", .driver = "rk8xx_rtc"}, 181 { }, 182 }; 183 184 static const struct pmic_child_info fuel_gauge_info[] = { 185 { .prefix = "battery", .driver = "rk818_fg"}, 186 { .prefix = "battery", .driver = "rk817_fg"}, 187 { .prefix = "battery", .driver = "rk816_fg"}, 188 { }, 189 }; 190 191 static const struct pmic_child_info rk817_codec_info[] = { 192 { .prefix = "codec", .driver = "rk817_codec"}, 193 { }, 194 }; 195 196 static int rk8xx_reg_count(struct udevice *dev) 197 { 198 return RK808_NUM_OF_REGS; 199 } 200 201 static int rk8xx_write(struct udevice *dev, uint reg, const uint8_t *buff, 202 int len) 203 { 204 int ret; 205 206 ret = dm_i2c_write(dev, reg, buff, len); 207 if (ret) { 208 printf("%s: write reg 0x%02x failed, ret=%d\n", __func__, reg, ret); 209 return ret; 210 } 211 212 return 0; 213 } 214 215 static int rk8xx_read(struct udevice *dev, uint reg, uint8_t *buff, int len) 216 { 217 int ret; 218 219 ret = dm_i2c_read(dev, reg, buff, len); 220 if (ret) { 221 printf("%s: read reg 0x%02x failed, ret=%d\n", __func__, reg, ret); 222 return ret; 223 } 224 225 return 0; 226 } 227 228 static int rk8xx_shutdown(struct udevice *dev) 229 { 230 struct rk8xx_priv *priv = dev_get_priv(dev); 231 u8 val, dev_off, devctrl_reg; 232 int ret = 0; 233 234 switch (priv->variant) { 235 case RK808_ID: 236 devctrl_reg = REG_DEVCTRL; 237 dev_off = BIT(3); 238 break; 239 case RK805_ID: 240 case RK816_ID: 241 case RK818_ID: 242 devctrl_reg = REG_DEVCTRL; 243 dev_off = BIT(0); 244 break; 245 case RK809_ID: 246 case RK817_ID: 247 devctrl_reg = RK817_REG_SYS_CFG3; 248 dev_off = BIT(0); 249 break; 250 default: 251 printf("Unknown PMIC: RK%x\n", priv->variant); 252 return -EINVAL; 253 } 254 255 ret = dm_i2c_read(dev, devctrl_reg, &val, 1); 256 if (ret) { 257 printf("%s: read reg 0x%02x failed, ret=%d\n", 258 __func__, devctrl_reg, ret); 259 return ret; 260 } 261 262 val |= dev_off; 263 ret = dm_i2c_write(dev, devctrl_reg, &val, 1); 264 if (ret) { 265 printf("%s: write reg 0x%02x failed, ret=%d\n", 266 __func__, devctrl_reg, ret); 267 return ret; 268 } 269 270 return 0; 271 } 272 273 /* 274 * When system suspend during U-Boot charge, make sure the plugout event 275 * be able to wakeup cpu in wfi/wfe state. 276 */ 277 #ifdef CONFIG_DM_CHARGE_DISPLAY 278 static void rk8xx_plug_out_handler(int irq, void *data) 279 { 280 printf("Plug out interrupt\n"); 281 } 282 #endif 283 284 #if CONFIG_IS_ENABLED(PMIC_CHILDREN) 285 static int rk8xx_bind(struct udevice *dev) 286 { 287 ofnode regulators_node; 288 int children; 289 290 regulators_node = dev_read_subnode(dev, "regulators"); 291 if (!ofnode_valid(regulators_node)) { 292 debug("%s: %s regulators subnode not found!\n", __func__, 293 dev->name); 294 return -ENXIO; 295 } 296 297 debug("%s: '%s' - found regulators subnode\n", __func__, dev->name); 298 299 children = pmic_bind_children(dev, regulators_node, pmic_children_info); 300 if (!children) 301 debug("%s: %s - no child found\n", __func__, dev->name); 302 303 children = pmic_bind_children(dev, dev->node, power_key_info); 304 if (!children) 305 debug("%s: %s - no child found\n", __func__, dev->name); 306 307 children = pmic_bind_children(dev, dev->node, rtc_info); 308 if (!children) 309 debug("%s: %s - no child found\n", __func__, dev->name); 310 311 children = pmic_bind_children(dev, dev->node, fuel_gauge_info); 312 if (!children) 313 debug("%s: %s - no child found\n", __func__, dev->name); 314 315 children = pmic_bind_children(dev, dev->node, rk817_codec_info); 316 if (!children) 317 debug("%s: %s - no child found\n", __func__, dev->name); 318 319 /* Always return success for this device */ 320 return 0; 321 } 322 #endif 323 324 #if defined(CONFIG_IRQ) && !defined(CONFIG_SPL_BUILD) 325 static int rk8xx_ofdata_to_platdata(struct udevice *dev) 326 { 327 struct rk8xx_priv *rk8xx = dev_get_priv(dev); 328 u32 interrupt, phandle; 329 int ret; 330 331 phandle = dev_read_u32_default(dev, "interrupt-parent", -ENODATA); 332 if (phandle == -ENODATA) { 333 printf("Read 'interrupt-parent' failed, ret=%d\n", phandle); 334 return phandle; 335 } 336 337 ret = dev_read_u32_array(dev, "interrupts", &interrupt, 1); 338 if (ret) { 339 printf("Read 'interrupts' failed, ret=%d\n", ret); 340 return ret; 341 } 342 343 rk8xx->irq = phandle_gpio_to_irq(phandle, interrupt); 344 if (rk8xx->irq < 0) { 345 printf("Failed to request rk8xx irq, ret=%d\n", rk8xx->irq); 346 return rk8xx->irq; 347 } 348 349 return 0; 350 } 351 352 static int rk8xx_irq_chip_init(struct udevice *dev) 353 { 354 struct rk8xx_priv *priv = dev_get_priv(dev); 355 struct virq_chip *irq_chip = NULL; 356 int ret; 357 358 switch (priv->variant) { 359 case RK808_ID: 360 irq_chip = &rk808_irq_chip; 361 break; 362 case RK805_ID: 363 irq_chip = &rk805_irq_chip; 364 break; 365 case RK816_ID: 366 irq_chip = &rk816_irq_chip; 367 break; 368 case RK818_ID: 369 irq_chip = &rk818_irq_chip; 370 break; 371 case RK809_ID: 372 case RK817_ID: 373 irq_chip = &rk817_irq_chip; 374 break; 375 default: 376 return -EINVAL; 377 } 378 379 if (irq_chip) { 380 ret = virq_add_chip(dev, irq_chip, priv->irq); 381 if (ret) { 382 printf("Failed to add irqchip(irq=%d), ret=%d\n", 383 priv->irq, ret); 384 return ret; 385 } 386 387 priv->irq_chip = irq_chip; 388 389 #ifdef CONFIG_DM_CHARGE_DISPLAY 390 int irq; 391 392 irq = virq_to_irq(irq_chip, RK8XX_IRQ_PLUG_OUT); 393 if (irq < 0) { 394 printf("Failed to register plugout irq, ret=%d\n", irq); 395 return irq; 396 } 397 irq_install_handler(irq, rk8xx_plug_out_handler, dev); 398 irq_handler_enable_suspend_only(irq); 399 #endif 400 } 401 402 return 0; 403 } 404 #else 405 static inline int rk8xx_ofdata_to_platdata(struct udevice *dev) { return 0; } 406 static inline int rk8xx_irq_chip_init(struct udevice *dev) { return 0; } 407 #endif 408 409 static int rk8xx_probe(struct udevice *dev) 410 { 411 struct rk8xx_priv *priv = dev_get_priv(dev); 412 struct reg_data *init_current = NULL; 413 struct reg_data *init_data = NULL; 414 int init_current_num = 0; 415 int init_data_num = 0; 416 int ret = 0, i, show_variant; 417 uint8_t msb, lsb, id_msb, id_lsb; 418 uint8_t on_source = 0, off_source = 0; 419 uint8_t power_en0, power_en1, power_en2, power_en3; 420 uint8_t value; 421 422 /* read Chip variant */ 423 if (device_is_compatible(dev, "rockchip,rk817") || 424 device_is_compatible(dev, "rockchip,rk809")) { 425 id_msb = RK817_ID_MSB; 426 id_lsb = RK817_ID_LSB; 427 } else { 428 id_msb = ID_MSB; 429 id_lsb = ID_LSB; 430 } 431 432 ret = rk8xx_read(dev, id_msb, &msb, 1); 433 if (ret) 434 return ret; 435 ret = rk8xx_read(dev, id_lsb, &lsb, 1); 436 if (ret) 437 return ret; 438 439 priv->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK; 440 show_variant = priv->variant; 441 switch (priv->variant) { 442 case RK808_ID: 443 show_variant = 0x808; /* RK808 hardware ID is 0 */ 444 break; 445 case RK805_ID: 446 case RK816_ID: 447 on_source = RK8XX_ON_SOURCE; 448 off_source = RK8XX_OFF_SOURCE; 449 break; 450 case RK818_ID: 451 on_source = RK8XX_ON_SOURCE; 452 off_source = RK8XX_OFF_SOURCE; 453 /* set current if no fuel gauge */ 454 if (!ofnode_valid(dev_read_subnode(dev, "battery"))) { 455 init_current = rk818_init_current; 456 init_current_num = ARRAY_SIZE(rk818_init_current); 457 } 458 break; 459 case RK809_ID: 460 case RK817_ID: 461 on_source = RK817_ON_SOURCE; 462 off_source = RK817_OFF_SOURCE; 463 init_data = rk817_init_reg; 464 init_data_num = ARRAY_SIZE(rk817_init_reg); 465 power_en0 = pmic_reg_read(dev, RK817_POWER_EN0); 466 power_en1 = pmic_reg_read(dev, RK817_POWER_EN1); 467 power_en2 = pmic_reg_read(dev, RK817_POWER_EN2); 468 power_en3 = pmic_reg_read(dev, RK817_POWER_EN3); 469 470 value = (power_en0 & 0x0f) | ((power_en1 & 0x0f) << 4); 471 pmic_reg_write(dev, RK817_POWER_EN_SAVE0, value); 472 value = (power_en2 & 0x0f) | ((power_en3 & 0x0f) << 4); 473 pmic_reg_write(dev, RK817_POWER_EN_SAVE1, value); 474 break; 475 default: 476 printf("Unknown PMIC: RK%x!!\n", priv->variant); 477 return -EINVAL; 478 } 479 480 /* common init */ 481 for (i = 0; i < init_data_num; i++) { 482 ret = pmic_clrsetbits(dev, 483 init_data[i].reg, 484 init_data[i].mask, 485 init_data[i].val); 486 if (ret < 0) { 487 printf("%s: i2c set reg 0x%x failed, ret=%d\n", 488 __func__, init_data[i].reg, ret); 489 } 490 } 491 492 /* current init */ 493 for (i = 0; i < init_current_num; i++) { 494 ret = pmic_clrsetbits(dev, 495 init_current[i].reg, 496 init_current[i].mask, 497 init_current[i].val); 498 if (ret < 0) { 499 printf("%s: i2c set reg 0x%x failed, ret=%d\n", 500 __func__, init_current[i].reg, ret); 501 } 502 } 503 504 printf("PMIC: RK%x ", show_variant); 505 506 if (on_source && off_source) 507 printf("(on=0x%02x, off=0x%02x)", 508 pmic_reg_read(dev, on_source), 509 pmic_reg_read(dev, off_source)); 510 printf("\n"); 511 512 ret = rk8xx_irq_chip_init(dev); 513 if (ret) { 514 printf("IRQ chip initial failed\n"); 515 return ret; 516 } 517 518 return 0; 519 } 520 521 static struct dm_pmic_ops rk8xx_ops = { 522 .reg_count = rk8xx_reg_count, 523 .read = rk8xx_read, 524 .write = rk8xx_write, 525 .shutdown = rk8xx_shutdown, 526 }; 527 528 static const struct udevice_id rk8xx_ids[] = { 529 { .compatible = "rockchip,rk805" }, 530 { .compatible = "rockchip,rk808" }, 531 { .compatible = "rockchip,rk809" }, 532 { .compatible = "rockchip,rk816" }, 533 { .compatible = "rockchip,rk817" }, 534 { .compatible = "rockchip,rk818" }, 535 { } 536 }; 537 538 U_BOOT_DRIVER(pmic_rk8xx) = { 539 .name = "rk8xx pmic", 540 .id = UCLASS_PMIC, 541 .of_match = rk8xx_ids, 542 #if CONFIG_IS_ENABLED(PMIC_CHILDREN) 543 .bind = rk8xx_bind, 544 #endif 545 .ofdata_to_platdata = rk8xx_ofdata_to_platdata, 546 .priv_auto_alloc_size = sizeof(struct rk8xx_priv), 547 .probe = rk8xx_probe, 548 .ops = &rk8xx_ops, 549 }; 550