1 /* 2 * linux/drivers/i2c/chips/twl4030-power.c 3 * 4 * Handle TWL4030 Power initialization 5 * 6 * Copyright (C) 2008 Nokia Corporation 7 * Copyright (C) 2006 Texas Instruments, Inc 8 * 9 * Written by Kalle Jokiniemi 10 * Peter De Schrijver <peter.de-schrijver@nokia.com> 11 * Several fixes by Amit Kucheria <amit.kucheria@verdurent.com> 12 * 13 * This file is subject to the terms and conditions of the GNU General 14 * Public License. See the file "COPYING" in the main directory of this 15 * archive for more details. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 */ 26 27 #include <linux/module.h> 28 #include <linux/pm.h> 29 #include <linux/i2c/twl.h> 30 #include <linux/platform_device.h> 31 #include <linux/of.h> 32 33 #include <asm/mach-types.h> 34 35 static u8 twl4030_start_script_address = 0x2b; 36 37 #define PWR_P1_SW_EVENTS 0x10 38 #define PWR_DEVOFF (1 << 0) 39 #define SEQ_OFFSYNC (1 << 0) 40 41 #define PHY_TO_OFF_PM_MASTER(p) (p - 0x36) 42 #define PHY_TO_OFF_PM_RECEIVER(p) (p - 0x5b) 43 44 /* resource - hfclk */ 45 #define R_HFCLKOUT_DEV_GRP PHY_TO_OFF_PM_RECEIVER(0xe6) 46 47 /* PM events */ 48 #define R_P1_SW_EVENTS PHY_TO_OFF_PM_MASTER(0x46) 49 #define R_P2_SW_EVENTS PHY_TO_OFF_PM_MASTER(0x47) 50 #define R_P3_SW_EVENTS PHY_TO_OFF_PM_MASTER(0x48) 51 #define R_CFG_P1_TRANSITION PHY_TO_OFF_PM_MASTER(0x36) 52 #define R_CFG_P2_TRANSITION PHY_TO_OFF_PM_MASTER(0x37) 53 #define R_CFG_P3_TRANSITION PHY_TO_OFF_PM_MASTER(0x38) 54 55 #define LVL_WAKEUP 0x08 56 57 #define ENABLE_WARMRESET (1<<4) 58 59 #define END_OF_SCRIPT 0x3f 60 61 #define R_SEQ_ADD_A2S PHY_TO_OFF_PM_MASTER(0x55) 62 #define R_SEQ_ADD_S2A12 PHY_TO_OFF_PM_MASTER(0x56) 63 #define R_SEQ_ADD_S2A3 PHY_TO_OFF_PM_MASTER(0x57) 64 #define R_SEQ_ADD_WARM PHY_TO_OFF_PM_MASTER(0x58) 65 #define R_MEMORY_ADDRESS PHY_TO_OFF_PM_MASTER(0x59) 66 #define R_MEMORY_DATA PHY_TO_OFF_PM_MASTER(0x5a) 67 68 /* resource configuration registers 69 <RESOURCE>_DEV_GRP at address 'n+0' 70 <RESOURCE>_TYPE at address 'n+1' 71 <RESOURCE>_REMAP at address 'n+2' 72 <RESOURCE>_DEDICATED at address 'n+3' 73 */ 74 #define DEV_GRP_OFFSET 0 75 #define TYPE_OFFSET 1 76 #define REMAP_OFFSET 2 77 #define DEDICATED_OFFSET 3 78 79 /* Bit positions in the registers */ 80 81 /* <RESOURCE>_DEV_GRP */ 82 #define DEV_GRP_SHIFT 5 83 #define DEV_GRP_MASK (7 << DEV_GRP_SHIFT) 84 85 /* <RESOURCE>_TYPE */ 86 #define TYPE_SHIFT 0 87 #define TYPE_MASK (7 << TYPE_SHIFT) 88 #define TYPE2_SHIFT 3 89 #define TYPE2_MASK (3 << TYPE2_SHIFT) 90 91 /* <RESOURCE>_REMAP */ 92 #define SLEEP_STATE_SHIFT 0 93 #define SLEEP_STATE_MASK (0xf << SLEEP_STATE_SHIFT) 94 #define OFF_STATE_SHIFT 4 95 #define OFF_STATE_MASK (0xf << OFF_STATE_SHIFT) 96 97 static u8 res_config_addrs[] = { 98 [RES_VAUX1] = 0x17, 99 [RES_VAUX2] = 0x1b, 100 [RES_VAUX3] = 0x1f, 101 [RES_VAUX4] = 0x23, 102 [RES_VMMC1] = 0x27, 103 [RES_VMMC2] = 0x2b, 104 [RES_VPLL1] = 0x2f, 105 [RES_VPLL2] = 0x33, 106 [RES_VSIM] = 0x37, 107 [RES_VDAC] = 0x3b, 108 [RES_VINTANA1] = 0x3f, 109 [RES_VINTANA2] = 0x43, 110 [RES_VINTDIG] = 0x47, 111 [RES_VIO] = 0x4b, 112 [RES_VDD1] = 0x55, 113 [RES_VDD2] = 0x63, 114 [RES_VUSB_1V5] = 0x71, 115 [RES_VUSB_1V8] = 0x74, 116 [RES_VUSB_3V1] = 0x77, 117 [RES_VUSBCP] = 0x7a, 118 [RES_REGEN] = 0x7f, 119 [RES_NRES_PWRON] = 0x82, 120 [RES_CLKEN] = 0x85, 121 [RES_SYSEN] = 0x88, 122 [RES_HFCLKOUT] = 0x8b, 123 [RES_32KCLKOUT] = 0x8e, 124 [RES_RESET] = 0x91, 125 [RES_MAIN_REF] = 0x94, 126 }; 127 128 static int twl4030_write_script_byte(u8 address, u8 byte) 129 { 130 int err; 131 132 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_MEMORY_ADDRESS); 133 if (err) 134 goto out; 135 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, byte, R_MEMORY_DATA); 136 out: 137 return err; 138 } 139 140 static int twl4030_write_script_ins(u8 address, u16 pmb_message, 141 u8 delay, u8 next) 142 { 143 int err; 144 145 address *= 4; 146 err = twl4030_write_script_byte(address++, pmb_message >> 8); 147 if (err) 148 goto out; 149 err = twl4030_write_script_byte(address++, pmb_message & 0xff); 150 if (err) 151 goto out; 152 err = twl4030_write_script_byte(address++, delay); 153 if (err) 154 goto out; 155 err = twl4030_write_script_byte(address++, next); 156 out: 157 return err; 158 } 159 160 static int twl4030_write_script(u8 address, struct twl4030_ins *script, 161 int len) 162 { 163 int err = -EINVAL; 164 165 for (; len; len--, address++, script++) { 166 if (len == 1) { 167 err = twl4030_write_script_ins(address, 168 script->pmb_message, 169 script->delay, 170 END_OF_SCRIPT); 171 if (err) 172 break; 173 } else { 174 err = twl4030_write_script_ins(address, 175 script->pmb_message, 176 script->delay, 177 address + 1); 178 if (err) 179 break; 180 } 181 } 182 return err; 183 } 184 185 static int twl4030_config_wakeup3_sequence(u8 address) 186 { 187 int err; 188 u8 data; 189 190 /* Set SLEEP to ACTIVE SEQ address for P3 */ 191 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_S2A3); 192 if (err) 193 goto out; 194 195 /* P3 LVL_WAKEUP should be on LEVEL */ 196 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P3_SW_EVENTS); 197 if (err) 198 goto out; 199 data |= LVL_WAKEUP; 200 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P3_SW_EVENTS); 201 out: 202 if (err) 203 pr_err("TWL4030 wakeup sequence for P3 config error\n"); 204 return err; 205 } 206 207 static int twl4030_config_wakeup12_sequence(u8 address) 208 { 209 int err = 0; 210 u8 data; 211 212 /* Set SLEEP to ACTIVE SEQ address for P1 and P2 */ 213 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_S2A12); 214 if (err) 215 goto out; 216 217 /* P1/P2 LVL_WAKEUP should be on LEVEL */ 218 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P1_SW_EVENTS); 219 if (err) 220 goto out; 221 222 data |= LVL_WAKEUP; 223 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P1_SW_EVENTS); 224 if (err) 225 goto out; 226 227 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P2_SW_EVENTS); 228 if (err) 229 goto out; 230 231 data |= LVL_WAKEUP; 232 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P2_SW_EVENTS); 233 if (err) 234 goto out; 235 236 if (machine_is_omap_3430sdp() || machine_is_omap_ldp()) { 237 /* Disabling AC charger effect on sleep-active transitions */ 238 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, 239 R_CFG_P1_TRANSITION); 240 if (err) 241 goto out; 242 data &= ~(1<<1); 243 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, 244 R_CFG_P1_TRANSITION); 245 if (err) 246 goto out; 247 } 248 249 out: 250 if (err) 251 pr_err("TWL4030 wakeup sequence for P1 and P2" \ 252 "config error\n"); 253 return err; 254 } 255 256 static int twl4030_config_sleep_sequence(u8 address) 257 { 258 int err; 259 260 /* Set ACTIVE to SLEEP SEQ address in T2 memory*/ 261 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_A2S); 262 263 if (err) 264 pr_err("TWL4030 sleep sequence config error\n"); 265 266 return err; 267 } 268 269 static int twl4030_config_warmreset_sequence(u8 address) 270 { 271 int err; 272 u8 rd_data; 273 274 /* Set WARM RESET SEQ address for P1 */ 275 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_WARM); 276 if (err) 277 goto out; 278 279 /* P1/P2/P3 enable WARMRESET */ 280 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P1_SW_EVENTS); 281 if (err) 282 goto out; 283 284 rd_data |= ENABLE_WARMRESET; 285 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P1_SW_EVENTS); 286 if (err) 287 goto out; 288 289 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P2_SW_EVENTS); 290 if (err) 291 goto out; 292 293 rd_data |= ENABLE_WARMRESET; 294 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P2_SW_EVENTS); 295 if (err) 296 goto out; 297 298 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P3_SW_EVENTS); 299 if (err) 300 goto out; 301 302 rd_data |= ENABLE_WARMRESET; 303 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P3_SW_EVENTS); 304 out: 305 if (err) 306 pr_err("TWL4030 warmreset seq config error\n"); 307 return err; 308 } 309 310 static int twl4030_configure_resource(struct twl4030_resconfig *rconfig) 311 { 312 int rconfig_addr; 313 int err; 314 u8 type; 315 u8 grp; 316 u8 remap; 317 318 if (rconfig->resource > TOTAL_RESOURCES) { 319 pr_err("TWL4030 Resource %d does not exist\n", 320 rconfig->resource); 321 return -EINVAL; 322 } 323 324 rconfig_addr = res_config_addrs[rconfig->resource]; 325 326 /* Set resource group */ 327 err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &grp, 328 rconfig_addr + DEV_GRP_OFFSET); 329 if (err) { 330 pr_err("TWL4030 Resource %d group could not be read\n", 331 rconfig->resource); 332 return err; 333 } 334 335 if (rconfig->devgroup != TWL4030_RESCONFIG_UNDEF) { 336 grp &= ~DEV_GRP_MASK; 337 grp |= rconfig->devgroup << DEV_GRP_SHIFT; 338 err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 339 grp, rconfig_addr + DEV_GRP_OFFSET); 340 if (err < 0) { 341 pr_err("TWL4030 failed to program devgroup\n"); 342 return err; 343 } 344 } 345 346 /* Set resource types */ 347 err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &type, 348 rconfig_addr + TYPE_OFFSET); 349 if (err < 0) { 350 pr_err("TWL4030 Resource %d type could not be read\n", 351 rconfig->resource); 352 return err; 353 } 354 355 if (rconfig->type != TWL4030_RESCONFIG_UNDEF) { 356 type &= ~TYPE_MASK; 357 type |= rconfig->type << TYPE_SHIFT; 358 } 359 360 if (rconfig->type2 != TWL4030_RESCONFIG_UNDEF) { 361 type &= ~TYPE2_MASK; 362 type |= rconfig->type2 << TYPE2_SHIFT; 363 } 364 365 err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 366 type, rconfig_addr + TYPE_OFFSET); 367 if (err < 0) { 368 pr_err("TWL4030 failed to program resource type\n"); 369 return err; 370 } 371 372 /* Set remap states */ 373 err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &remap, 374 rconfig_addr + REMAP_OFFSET); 375 if (err < 0) { 376 pr_err("TWL4030 Resource %d remap could not be read\n", 377 rconfig->resource); 378 return err; 379 } 380 381 if (rconfig->remap_off != TWL4030_RESCONFIG_UNDEF) { 382 remap &= ~OFF_STATE_MASK; 383 remap |= rconfig->remap_off << OFF_STATE_SHIFT; 384 } 385 386 if (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF) { 387 remap &= ~SLEEP_STATE_MASK; 388 remap |= rconfig->remap_sleep << SLEEP_STATE_SHIFT; 389 } 390 391 err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 392 remap, 393 rconfig_addr + REMAP_OFFSET); 394 if (err < 0) { 395 pr_err("TWL4030 failed to program remap\n"); 396 return err; 397 } 398 399 return 0; 400 } 401 402 static int load_twl4030_script(struct twl4030_script *tscript, 403 u8 address) 404 { 405 int err; 406 static int order; 407 408 /* Make sure the script isn't going beyond last valid address (0x3f) */ 409 if ((address + tscript->size) > END_OF_SCRIPT) { 410 pr_err("TWL4030 scripts too big error\n"); 411 return -EINVAL; 412 } 413 414 err = twl4030_write_script(address, tscript->script, tscript->size); 415 if (err) 416 goto out; 417 418 if (tscript->flags & TWL4030_WRST_SCRIPT) { 419 err = twl4030_config_warmreset_sequence(address); 420 if (err) 421 goto out; 422 } 423 if (tscript->flags & TWL4030_WAKEUP12_SCRIPT) { 424 err = twl4030_config_wakeup12_sequence(address); 425 if (err) 426 goto out; 427 order = 1; 428 } 429 if (tscript->flags & TWL4030_WAKEUP3_SCRIPT) { 430 err = twl4030_config_wakeup3_sequence(address); 431 if (err) 432 goto out; 433 } 434 if (tscript->flags & TWL4030_SLEEP_SCRIPT) { 435 if (!order) 436 pr_warning("TWL4030: Bad order of scripts (sleep "\ 437 "script before wakeup) Leads to boot"\ 438 "failure on some boards\n"); 439 err = twl4030_config_sleep_sequence(address); 440 } 441 out: 442 return err; 443 } 444 445 int twl4030_remove_script(u8 flags) 446 { 447 int err = 0; 448 449 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1, 450 TWL4030_PM_MASTER_PROTECT_KEY); 451 if (err) { 452 pr_err("twl4030: unable to unlock PROTECT_KEY\n"); 453 return err; 454 } 455 456 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2, 457 TWL4030_PM_MASTER_PROTECT_KEY); 458 if (err) { 459 pr_err("twl4030: unable to unlock PROTECT_KEY\n"); 460 return err; 461 } 462 463 if (flags & TWL4030_WRST_SCRIPT) { 464 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT, 465 R_SEQ_ADD_WARM); 466 if (err) 467 return err; 468 } 469 if (flags & TWL4030_WAKEUP12_SCRIPT) { 470 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT, 471 R_SEQ_ADD_S2A12); 472 if (err) 473 return err; 474 } 475 if (flags & TWL4030_WAKEUP3_SCRIPT) { 476 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT, 477 R_SEQ_ADD_S2A3); 478 if (err) 479 return err; 480 } 481 if (flags & TWL4030_SLEEP_SCRIPT) { 482 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT, 483 R_SEQ_ADD_A2S); 484 if (err) 485 return err; 486 } 487 488 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0, 489 TWL4030_PM_MASTER_PROTECT_KEY); 490 if (err) 491 pr_err("TWL4030 Unable to relock registers\n"); 492 493 return err; 494 } 495 496 static int twl4030_power_configure_scripts(struct twl4030_power_data *pdata) 497 { 498 int err; 499 int i; 500 u8 address = twl4030_start_script_address; 501 502 for (i = 0; i < pdata->num; i++) { 503 err = load_twl4030_script(pdata->scripts[i], address); 504 if (err) 505 return err; 506 address += pdata->scripts[i]->size; 507 } 508 509 return 0; 510 } 511 512 static int twl4030_power_configure_resources(struct twl4030_power_data *pdata) 513 { 514 struct twl4030_resconfig *resconfig = pdata->resource_config; 515 int err; 516 517 if (resconfig) { 518 while (resconfig->resource) { 519 err = twl4030_configure_resource(resconfig); 520 if (err) 521 return err; 522 resconfig++; 523 } 524 } 525 526 return 0; 527 } 528 529 /* 530 * In master mode, start the power off sequence. 531 * After a successful execution, TWL shuts down the power to the SoC 532 * and all peripherals connected to it. 533 */ 534 void twl4030_power_off(void) 535 { 536 int err; 537 538 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, PWR_DEVOFF, 539 TWL4030_PM_MASTER_P1_SW_EVENTS); 540 if (err) 541 pr_err("TWL4030 Unable to power off\n"); 542 } 543 544 static bool twl4030_power_use_poweroff(struct twl4030_power_data *pdata, 545 struct device_node *node) 546 { 547 if (pdata && pdata->use_poweroff) 548 return true; 549 550 if (of_property_read_bool(node, "ti,use_poweroff")) 551 return true; 552 553 return false; 554 } 555 556 static int twl4030_power_probe(struct platform_device *pdev) 557 { 558 struct twl4030_power_data *pdata = dev_get_platdata(&pdev->dev); 559 struct device_node *node = pdev->dev.of_node; 560 int err = 0; 561 int err2 = 0; 562 u8 val; 563 564 if (!pdata && !node) { 565 dev_err(&pdev->dev, "Platform data is missing\n"); 566 return -EINVAL; 567 } 568 569 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1, 570 TWL4030_PM_MASTER_PROTECT_KEY); 571 err |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 572 TWL4030_PM_MASTER_KEY_CFG2, 573 TWL4030_PM_MASTER_PROTECT_KEY); 574 575 if (err) { 576 pr_err("TWL4030 Unable to unlock registers\n"); 577 return err; 578 } 579 580 if (pdata) { 581 /* TODO: convert to device tree */ 582 err = twl4030_power_configure_scripts(pdata); 583 if (err) { 584 pr_err("TWL4030 failed to load scripts\n"); 585 goto relock; 586 } 587 err = twl4030_power_configure_resources(pdata); 588 if (err) { 589 pr_err("TWL4030 failed to configure resource\n"); 590 goto relock; 591 } 592 } 593 594 /* Board has to be wired properly to use this feature */ 595 if (twl4030_power_use_poweroff(pdata, node) && !pm_power_off) { 596 /* Default for SEQ_OFFSYNC is set, lets ensure this */ 597 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &val, 598 TWL4030_PM_MASTER_CFG_P123_TRANSITION); 599 if (err) { 600 pr_warning("TWL4030 Unable to read registers\n"); 601 602 } else if (!(val & SEQ_OFFSYNC)) { 603 val |= SEQ_OFFSYNC; 604 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, val, 605 TWL4030_PM_MASTER_CFG_P123_TRANSITION); 606 if (err) { 607 pr_err("TWL4030 Unable to setup SEQ_OFFSYNC\n"); 608 goto relock; 609 } 610 } 611 612 pm_power_off = twl4030_power_off; 613 } 614 615 relock: 616 err2 = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0, 617 TWL4030_PM_MASTER_PROTECT_KEY); 618 if (err2) { 619 pr_err("TWL4030 Unable to relock registers\n"); 620 return err2; 621 } 622 623 return err; 624 } 625 626 static int twl4030_power_remove(struct platform_device *pdev) 627 { 628 return 0; 629 } 630 631 #ifdef CONFIG_OF 632 static const struct of_device_id twl4030_power_of_match[] = { 633 {.compatible = "ti,twl4030-power", }, 634 { }, 635 }; 636 MODULE_DEVICE_TABLE(of, twl4030_power_of_match); 637 #endif 638 639 static struct platform_driver twl4030_power_driver = { 640 .driver = { 641 .name = "twl4030_power", 642 .owner = THIS_MODULE, 643 .of_match_table = of_match_ptr(twl4030_power_of_match), 644 }, 645 .probe = twl4030_power_probe, 646 .remove = twl4030_power_remove, 647 }; 648 649 module_platform_driver(twl4030_power_driver); 650 651 MODULE_AUTHOR("Nokia Corporation"); 652 MODULE_AUTHOR("Texas Instruments, Inc."); 653 MODULE_DESCRIPTION("Power management for TWL4030"); 654 MODULE_LICENSE("GPL"); 655 MODULE_ALIAS("platform:twl4030_power"); 656