1 /* 2 * 3 * Handle TWL4030 Power initialization 4 * 5 * Copyright (C) 2008 Nokia Corporation 6 * Copyright (C) 2006 Texas Instruments, Inc 7 * 8 * Written by Kalle Jokiniemi 9 * Peter De Schrijver <peter.de-schrijver@nokia.com> 10 * Several fixes by Amit Kucheria <amit.kucheria@verdurent.com> 11 * 12 * This file is subject to the terms and conditions of the GNU General 13 * Public License. See the file "COPYING" in the main directory of this 14 * archive for more details. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 */ 25 26 #include <linux/module.h> 27 #include <linux/pm.h> 28 #include <linux/i2c/twl.h> 29 #include <linux/platform_device.h> 30 #include <linux/of.h> 31 #include <linux/of_device.h> 32 33 #include <asm/mach-types.h> 34 35 static u8 twl4030_start_script_address = 0x2b; 36 37 /* Register bits for P1, P2 and P3_SW_EVENTS */ 38 #define PWR_STOPON_PRWON BIT(6) 39 #define PWR_STOPON_SYSEN BIT(5) 40 #define PWR_ENABLE_WARMRESET BIT(4) 41 #define PWR_LVL_WAKEUP BIT(3) 42 #define PWR_DEVACT BIT(2) 43 #define PWR_DEVSLP BIT(1) 44 #define PWR_DEVOFF BIT(0) 45 46 /* Register bits for CFG_P1_TRANSITION (also for P2 and P3) */ 47 #define STARTON_SWBUG BIT(7) /* Start on watchdog */ 48 #define STARTON_VBUS BIT(5) /* Start on VBUS */ 49 #define STARTON_VBAT BIT(4) /* Start on battery insert */ 50 #define STARTON_RTC BIT(3) /* Start on RTC */ 51 #define STARTON_USB BIT(2) /* Start on USB host */ 52 #define STARTON_CHG BIT(1) /* Start on charger */ 53 #define STARTON_PWON BIT(0) /* Start on PWRON button */ 54 55 #define SEQ_OFFSYNC (1 << 0) 56 57 #define PHY_TO_OFF_PM_MASTER(p) (p - 0x36) 58 #define PHY_TO_OFF_PM_RECEIVER(p) (p - 0x5b) 59 60 /* resource - hfclk */ 61 #define R_HFCLKOUT_DEV_GRP PHY_TO_OFF_PM_RECEIVER(0xe6) 62 63 /* PM events */ 64 #define R_P1_SW_EVENTS PHY_TO_OFF_PM_MASTER(0x46) 65 #define R_P2_SW_EVENTS PHY_TO_OFF_PM_MASTER(0x47) 66 #define R_P3_SW_EVENTS PHY_TO_OFF_PM_MASTER(0x48) 67 #define R_CFG_P1_TRANSITION PHY_TO_OFF_PM_MASTER(0x36) 68 #define R_CFG_P2_TRANSITION PHY_TO_OFF_PM_MASTER(0x37) 69 #define R_CFG_P3_TRANSITION PHY_TO_OFF_PM_MASTER(0x38) 70 71 #define END_OF_SCRIPT 0x3f 72 73 #define R_SEQ_ADD_A2S PHY_TO_OFF_PM_MASTER(0x55) 74 #define R_SEQ_ADD_S2A12 PHY_TO_OFF_PM_MASTER(0x56) 75 #define R_SEQ_ADD_S2A3 PHY_TO_OFF_PM_MASTER(0x57) 76 #define R_SEQ_ADD_WARM PHY_TO_OFF_PM_MASTER(0x58) 77 #define R_MEMORY_ADDRESS PHY_TO_OFF_PM_MASTER(0x59) 78 #define R_MEMORY_DATA PHY_TO_OFF_PM_MASTER(0x5a) 79 80 /* resource configuration registers 81 <RESOURCE>_DEV_GRP at address 'n+0' 82 <RESOURCE>_TYPE at address 'n+1' 83 <RESOURCE>_REMAP at address 'n+2' 84 <RESOURCE>_DEDICATED at address 'n+3' 85 */ 86 #define DEV_GRP_OFFSET 0 87 #define TYPE_OFFSET 1 88 #define REMAP_OFFSET 2 89 #define DEDICATED_OFFSET 3 90 91 /* Bit positions in the registers */ 92 93 /* <RESOURCE>_DEV_GRP */ 94 #define DEV_GRP_SHIFT 5 95 #define DEV_GRP_MASK (7 << DEV_GRP_SHIFT) 96 97 /* <RESOURCE>_TYPE */ 98 #define TYPE_SHIFT 0 99 #define TYPE_MASK (7 << TYPE_SHIFT) 100 #define TYPE2_SHIFT 3 101 #define TYPE2_MASK (3 << TYPE2_SHIFT) 102 103 /* <RESOURCE>_REMAP */ 104 #define SLEEP_STATE_SHIFT 0 105 #define SLEEP_STATE_MASK (0xf << SLEEP_STATE_SHIFT) 106 #define OFF_STATE_SHIFT 4 107 #define OFF_STATE_MASK (0xf << OFF_STATE_SHIFT) 108 109 static u8 res_config_addrs[] = { 110 [RES_VAUX1] = 0x17, 111 [RES_VAUX2] = 0x1b, 112 [RES_VAUX3] = 0x1f, 113 [RES_VAUX4] = 0x23, 114 [RES_VMMC1] = 0x27, 115 [RES_VMMC2] = 0x2b, 116 [RES_VPLL1] = 0x2f, 117 [RES_VPLL2] = 0x33, 118 [RES_VSIM] = 0x37, 119 [RES_VDAC] = 0x3b, 120 [RES_VINTANA1] = 0x3f, 121 [RES_VINTANA2] = 0x43, 122 [RES_VINTDIG] = 0x47, 123 [RES_VIO] = 0x4b, 124 [RES_VDD1] = 0x55, 125 [RES_VDD2] = 0x63, 126 [RES_VUSB_1V5] = 0x71, 127 [RES_VUSB_1V8] = 0x74, 128 [RES_VUSB_3V1] = 0x77, 129 [RES_VUSBCP] = 0x7a, 130 [RES_REGEN] = 0x7f, 131 [RES_NRES_PWRON] = 0x82, 132 [RES_CLKEN] = 0x85, 133 [RES_SYSEN] = 0x88, 134 [RES_HFCLKOUT] = 0x8b, 135 [RES_32KCLKOUT] = 0x8e, 136 [RES_RESET] = 0x91, 137 [RES_MAIN_REF] = 0x94, 138 }; 139 140 /* 141 * Usable values for .remap_sleep and .remap_off 142 * Based on table "5.3.3 Resource Operating modes" 143 */ 144 enum { 145 TWL_REMAP_OFF = 0, 146 TWL_REMAP_SLEEP = 8, 147 TWL_REMAP_ACTIVE = 9, 148 }; 149 150 /* 151 * Macros to configure the PM register states for various resources. 152 * Note that we can make MSG_SINGULAR etc private to this driver once 153 * omap3 has been made DT only. 154 */ 155 #define TWL_DFLT_DELAY 2 /* typically 2 32 KiHz cycles */ 156 #define TWL_DEV_GRP_P123 (DEV_GRP_P1 | DEV_GRP_P2 | DEV_GRP_P3) 157 #define TWL_RESOURCE_SET(res, state) \ 158 { MSG_SINGULAR(DEV_GRP_NULL, (res), (state)), TWL_DFLT_DELAY } 159 #define TWL_RESOURCE_ON(res) TWL_RESOURCE_SET(res, RES_STATE_ACTIVE) 160 #define TWL_RESOURCE_OFF(res) TWL_RESOURCE_SET(res, RES_STATE_OFF) 161 #define TWL_RESOURCE_RESET(res) TWL_RESOURCE_SET(res, RES_STATE_WRST) 162 /* 163 * It seems that type1 and type2 is just the resource init order 164 * number for the type1 and type2 group. 165 */ 166 #define TWL_RESOURCE_SET_ACTIVE(res, state) \ 167 { MSG_SINGULAR(DEV_GRP_NULL, (res), RES_STATE_ACTIVE), (state) } 168 #define TWL_RESOURCE_GROUP_RESET(group, type1, type2) \ 169 { MSG_BROADCAST(DEV_GRP_NULL, (group), (type1), (type2), \ 170 RES_STATE_WRST), TWL_DFLT_DELAY } 171 #define TWL_RESOURCE_GROUP_SLEEP(group, type, type2) \ 172 { MSG_BROADCAST(DEV_GRP_NULL, (group), (type), (type2), \ 173 RES_STATE_SLEEP), TWL_DFLT_DELAY } 174 #define TWL_RESOURCE_GROUP_ACTIVE(group, type, type2) \ 175 { MSG_BROADCAST(DEV_GRP_NULL, (group), (type), (type2), \ 176 RES_STATE_ACTIVE), TWL_DFLT_DELAY } 177 #define TWL_REMAP_SLEEP(res, devgrp, typ, typ2) \ 178 { .resource = (res), .devgroup = (devgrp), \ 179 .type = (typ), .type2 = (typ2), \ 180 .remap_off = TWL_REMAP_OFF, \ 181 .remap_sleep = TWL_REMAP_SLEEP, } 182 #define TWL_REMAP_OFF(res, devgrp, typ, typ2) \ 183 { .resource = (res), .devgroup = (devgrp), \ 184 .type = (typ), .type2 = (typ2), \ 185 .remap_off = TWL_REMAP_OFF, .remap_sleep = TWL_REMAP_OFF, } 186 187 static int twl4030_write_script_byte(u8 address, u8 byte) 188 { 189 int err; 190 191 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_MEMORY_ADDRESS); 192 if (err) 193 goto out; 194 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, byte, R_MEMORY_DATA); 195 out: 196 return err; 197 } 198 199 static int twl4030_write_script_ins(u8 address, u16 pmb_message, 200 u8 delay, u8 next) 201 { 202 int err; 203 204 address *= 4; 205 err = twl4030_write_script_byte(address++, pmb_message >> 8); 206 if (err) 207 goto out; 208 err = twl4030_write_script_byte(address++, pmb_message & 0xff); 209 if (err) 210 goto out; 211 err = twl4030_write_script_byte(address++, delay); 212 if (err) 213 goto out; 214 err = twl4030_write_script_byte(address++, next); 215 out: 216 return err; 217 } 218 219 static int twl4030_write_script(u8 address, struct twl4030_ins *script, 220 int len) 221 { 222 int err = -EINVAL; 223 224 for (; len; len--, address++, script++) { 225 if (len == 1) { 226 err = twl4030_write_script_ins(address, 227 script->pmb_message, 228 script->delay, 229 END_OF_SCRIPT); 230 if (err) 231 break; 232 } else { 233 err = twl4030_write_script_ins(address, 234 script->pmb_message, 235 script->delay, 236 address + 1); 237 if (err) 238 break; 239 } 240 } 241 return err; 242 } 243 244 static int twl4030_config_wakeup3_sequence(u8 address) 245 { 246 int err; 247 u8 data; 248 249 /* Set SLEEP to ACTIVE SEQ address for P3 */ 250 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_S2A3); 251 if (err) 252 goto out; 253 254 /* P3 LVL_WAKEUP should be on LEVEL */ 255 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P3_SW_EVENTS); 256 if (err) 257 goto out; 258 data |= PWR_LVL_WAKEUP; 259 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P3_SW_EVENTS); 260 out: 261 if (err) 262 pr_err("TWL4030 wakeup sequence for P3 config error\n"); 263 return err; 264 } 265 266 static int 267 twl4030_config_wakeup12_sequence(const struct twl4030_power_data *pdata, 268 u8 address) 269 { 270 int err = 0; 271 u8 data; 272 273 /* Set SLEEP to ACTIVE SEQ address for P1 and P2 */ 274 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_S2A12); 275 if (err) 276 goto out; 277 278 /* P1/P2 LVL_WAKEUP should be on LEVEL */ 279 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P1_SW_EVENTS); 280 if (err) 281 goto out; 282 283 data |= PWR_LVL_WAKEUP; 284 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P1_SW_EVENTS); 285 if (err) 286 goto out; 287 288 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P2_SW_EVENTS); 289 if (err) 290 goto out; 291 292 data |= PWR_LVL_WAKEUP; 293 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P2_SW_EVENTS); 294 if (err) 295 goto out; 296 297 if (pdata->ac_charger_quirk || machine_is_omap_3430sdp() || 298 machine_is_omap_ldp()) { 299 /* Disabling AC charger effect on sleep-active transitions */ 300 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, 301 R_CFG_P1_TRANSITION); 302 if (err) 303 goto out; 304 data &= ~STARTON_CHG; 305 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, 306 R_CFG_P1_TRANSITION); 307 if (err) 308 goto out; 309 } 310 311 out: 312 if (err) 313 pr_err("TWL4030 wakeup sequence for P1 and P2" \ 314 "config error\n"); 315 return err; 316 } 317 318 static int twl4030_config_sleep_sequence(u8 address) 319 { 320 int err; 321 322 /* Set ACTIVE to SLEEP SEQ address in T2 memory*/ 323 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_A2S); 324 325 if (err) 326 pr_err("TWL4030 sleep sequence config error\n"); 327 328 return err; 329 } 330 331 static int twl4030_config_warmreset_sequence(u8 address) 332 { 333 int err; 334 u8 rd_data; 335 336 /* Set WARM RESET SEQ address for P1 */ 337 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_WARM); 338 if (err) 339 goto out; 340 341 /* P1/P2/P3 enable WARMRESET */ 342 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P1_SW_EVENTS); 343 if (err) 344 goto out; 345 346 rd_data |= PWR_ENABLE_WARMRESET; 347 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P1_SW_EVENTS); 348 if (err) 349 goto out; 350 351 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P2_SW_EVENTS); 352 if (err) 353 goto out; 354 355 rd_data |= PWR_ENABLE_WARMRESET; 356 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P2_SW_EVENTS); 357 if (err) 358 goto out; 359 360 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P3_SW_EVENTS); 361 if (err) 362 goto out; 363 364 rd_data |= PWR_ENABLE_WARMRESET; 365 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P3_SW_EVENTS); 366 out: 367 if (err) 368 pr_err("TWL4030 warmreset seq config error\n"); 369 return err; 370 } 371 372 static int twl4030_configure_resource(struct twl4030_resconfig *rconfig) 373 { 374 int rconfig_addr; 375 int err; 376 u8 type; 377 u8 grp; 378 u8 remap; 379 380 if (rconfig->resource > TOTAL_RESOURCES) { 381 pr_err("TWL4030 Resource %d does not exist\n", 382 rconfig->resource); 383 return -EINVAL; 384 } 385 386 rconfig_addr = res_config_addrs[rconfig->resource]; 387 388 /* Set resource group */ 389 err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &grp, 390 rconfig_addr + DEV_GRP_OFFSET); 391 if (err) { 392 pr_err("TWL4030 Resource %d group could not be read\n", 393 rconfig->resource); 394 return err; 395 } 396 397 if (rconfig->devgroup != TWL4030_RESCONFIG_UNDEF) { 398 grp &= ~DEV_GRP_MASK; 399 grp |= rconfig->devgroup << DEV_GRP_SHIFT; 400 err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 401 grp, rconfig_addr + DEV_GRP_OFFSET); 402 if (err < 0) { 403 pr_err("TWL4030 failed to program devgroup\n"); 404 return err; 405 } 406 } 407 408 /* Set resource types */ 409 err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &type, 410 rconfig_addr + TYPE_OFFSET); 411 if (err < 0) { 412 pr_err("TWL4030 Resource %d type could not be read\n", 413 rconfig->resource); 414 return err; 415 } 416 417 if (rconfig->type != TWL4030_RESCONFIG_UNDEF) { 418 type &= ~TYPE_MASK; 419 type |= rconfig->type << TYPE_SHIFT; 420 } 421 422 if (rconfig->type2 != TWL4030_RESCONFIG_UNDEF) { 423 type &= ~TYPE2_MASK; 424 type |= rconfig->type2 << TYPE2_SHIFT; 425 } 426 427 err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 428 type, rconfig_addr + TYPE_OFFSET); 429 if (err < 0) { 430 pr_err("TWL4030 failed to program resource type\n"); 431 return err; 432 } 433 434 /* Set remap states */ 435 err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &remap, 436 rconfig_addr + REMAP_OFFSET); 437 if (err < 0) { 438 pr_err("TWL4030 Resource %d remap could not be read\n", 439 rconfig->resource); 440 return err; 441 } 442 443 if (rconfig->remap_off != TWL4030_RESCONFIG_UNDEF) { 444 remap &= ~OFF_STATE_MASK; 445 remap |= rconfig->remap_off << OFF_STATE_SHIFT; 446 } 447 448 if (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF) { 449 remap &= ~SLEEP_STATE_MASK; 450 remap |= rconfig->remap_sleep << SLEEP_STATE_SHIFT; 451 } 452 453 err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 454 remap, 455 rconfig_addr + REMAP_OFFSET); 456 if (err < 0) { 457 pr_err("TWL4030 failed to program remap\n"); 458 return err; 459 } 460 461 return 0; 462 } 463 464 static int load_twl4030_script(const struct twl4030_power_data *pdata, 465 struct twl4030_script *tscript, 466 u8 address) 467 { 468 int err; 469 static int order; 470 471 /* Make sure the script isn't going beyond last valid address (0x3f) */ 472 if ((address + tscript->size) > END_OF_SCRIPT) { 473 pr_err("TWL4030 scripts too big error\n"); 474 return -EINVAL; 475 } 476 477 err = twl4030_write_script(address, tscript->script, tscript->size); 478 if (err) 479 goto out; 480 481 if (tscript->flags & TWL4030_WRST_SCRIPT) { 482 err = twl4030_config_warmreset_sequence(address); 483 if (err) 484 goto out; 485 } 486 if (tscript->flags & TWL4030_WAKEUP12_SCRIPT) { 487 /* Reset any existing sleep script to avoid hangs on reboot */ 488 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT, 489 R_SEQ_ADD_A2S); 490 if (err) 491 goto out; 492 493 err = twl4030_config_wakeup12_sequence(pdata, address); 494 if (err) 495 goto out; 496 order = 1; 497 } 498 if (tscript->flags & TWL4030_WAKEUP3_SCRIPT) { 499 err = twl4030_config_wakeup3_sequence(address); 500 if (err) 501 goto out; 502 } 503 if (tscript->flags & TWL4030_SLEEP_SCRIPT) { 504 if (!order) 505 pr_warning("TWL4030: Bad order of scripts (sleep "\ 506 "script before wakeup) Leads to boot"\ 507 "failure on some boards\n"); 508 err = twl4030_config_sleep_sequence(address); 509 } 510 out: 511 return err; 512 } 513 514 int twl4030_remove_script(u8 flags) 515 { 516 int err = 0; 517 518 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1, 519 TWL4030_PM_MASTER_PROTECT_KEY); 520 if (err) { 521 pr_err("twl4030: unable to unlock PROTECT_KEY\n"); 522 return err; 523 } 524 525 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2, 526 TWL4030_PM_MASTER_PROTECT_KEY); 527 if (err) { 528 pr_err("twl4030: unable to unlock PROTECT_KEY\n"); 529 return err; 530 } 531 532 if (flags & TWL4030_WRST_SCRIPT) { 533 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT, 534 R_SEQ_ADD_WARM); 535 if (err) 536 return err; 537 } 538 if (flags & TWL4030_WAKEUP12_SCRIPT) { 539 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT, 540 R_SEQ_ADD_S2A12); 541 if (err) 542 return err; 543 } 544 if (flags & TWL4030_WAKEUP3_SCRIPT) { 545 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT, 546 R_SEQ_ADD_S2A3); 547 if (err) 548 return err; 549 } 550 if (flags & TWL4030_SLEEP_SCRIPT) { 551 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT, 552 R_SEQ_ADD_A2S); 553 if (err) 554 return err; 555 } 556 557 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0, 558 TWL4030_PM_MASTER_PROTECT_KEY); 559 if (err) 560 pr_err("TWL4030 Unable to relock registers\n"); 561 562 return err; 563 } 564 565 static int 566 twl4030_power_configure_scripts(const struct twl4030_power_data *pdata) 567 { 568 int err; 569 int i; 570 u8 address = twl4030_start_script_address; 571 572 for (i = 0; i < pdata->num; i++) { 573 err = load_twl4030_script(pdata, pdata->scripts[i], address); 574 if (err) 575 return err; 576 address += pdata->scripts[i]->size; 577 } 578 579 return 0; 580 } 581 582 static void twl4030_patch_rconfig(struct twl4030_resconfig *common, 583 struct twl4030_resconfig *board) 584 { 585 while (common->resource) { 586 struct twl4030_resconfig *b = board; 587 588 while (b->resource) { 589 if (b->resource == common->resource) { 590 *common = *b; 591 break; 592 } 593 b++; 594 } 595 common++; 596 } 597 } 598 599 static int 600 twl4030_power_configure_resources(const struct twl4030_power_data *pdata) 601 { 602 struct twl4030_resconfig *resconfig = pdata->resource_config; 603 struct twl4030_resconfig *boardconf = pdata->board_config; 604 int err; 605 606 if (resconfig) { 607 if (boardconf) 608 twl4030_patch_rconfig(resconfig, boardconf); 609 610 while (resconfig->resource) { 611 err = twl4030_configure_resource(resconfig); 612 if (err) 613 return err; 614 resconfig++; 615 } 616 } 617 618 return 0; 619 } 620 621 static int twl4030_starton_mask_and_set(u8 bitmask, u8 bitvalues) 622 { 623 u8 regs[3] = { TWL4030_PM_MASTER_CFG_P1_TRANSITION, 624 TWL4030_PM_MASTER_CFG_P2_TRANSITION, 625 TWL4030_PM_MASTER_CFG_P3_TRANSITION, }; 626 u8 val; 627 int i, err; 628 629 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1, 630 TWL4030_PM_MASTER_PROTECT_KEY); 631 if (err) 632 goto relock; 633 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 634 TWL4030_PM_MASTER_KEY_CFG2, 635 TWL4030_PM_MASTER_PROTECT_KEY); 636 if (err) 637 goto relock; 638 639 for (i = 0; i < sizeof(regs); i++) { 640 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, 641 &val, regs[i]); 642 if (err) 643 break; 644 val = (~bitmask & val) | (bitmask & bitvalues); 645 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 646 val, regs[i]); 647 if (err) 648 break; 649 } 650 651 if (err) 652 pr_err("TWL4030 Register access failed: %i\n", err); 653 654 relock: 655 return twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0, 656 TWL4030_PM_MASTER_PROTECT_KEY); 657 } 658 659 /* 660 * In master mode, start the power off sequence. 661 * After a successful execution, TWL shuts down the power to the SoC 662 * and all peripherals connected to it. 663 */ 664 void twl4030_power_off(void) 665 { 666 int err; 667 668 /* Disable start on charger or VBUS as it can break poweroff */ 669 err = twl4030_starton_mask_and_set(STARTON_VBUS | STARTON_CHG, 0); 670 if (err) 671 pr_err("TWL4030 Unable to configure start-up\n"); 672 673 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, PWR_DEVOFF, 674 TWL4030_PM_MASTER_P1_SW_EVENTS); 675 if (err) 676 pr_err("TWL4030 Unable to power off\n"); 677 } 678 679 static bool twl4030_power_use_poweroff(const struct twl4030_power_data *pdata, 680 struct device_node *node) 681 { 682 if (pdata && pdata->use_poweroff) 683 return true; 684 685 if (of_property_read_bool(node, "ti,system-power-controller")) 686 return true; 687 688 if (of_property_read_bool(node, "ti,use_poweroff")) 689 return true; 690 691 return false; 692 } 693 694 #ifdef CONFIG_OF 695 696 /* Generic warm reset configuration for omap3 */ 697 698 static struct twl4030_ins omap3_wrst_seq[] = { 699 TWL_RESOURCE_OFF(RES_NRES_PWRON), 700 TWL_RESOURCE_OFF(RES_RESET), 701 TWL_RESOURCE_RESET(RES_MAIN_REF), 702 TWL_RESOURCE_GROUP_RESET(RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2), 703 TWL_RESOURCE_RESET(RES_VUSB_3V1), 704 TWL_RESOURCE_GROUP_RESET(RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1), 705 TWL_RESOURCE_GROUP_RESET(RES_GRP_RC, RES_TYPE_ALL, RES_TYPE2_R0), 706 TWL_RESOURCE_ON(RES_RESET), 707 TWL_RESOURCE_ON(RES_NRES_PWRON), 708 }; 709 710 static struct twl4030_script omap3_wrst_script = { 711 .script = omap3_wrst_seq, 712 .size = ARRAY_SIZE(omap3_wrst_seq), 713 .flags = TWL4030_WRST_SCRIPT, 714 }; 715 716 static struct twl4030_script *omap3_reset_scripts[] = { 717 &omap3_wrst_script, 718 }; 719 720 static struct twl4030_resconfig omap3_rconfig[] = { 721 TWL_REMAP_SLEEP(RES_HFCLKOUT, DEV_GRP_P3, -1, -1), 722 TWL_REMAP_SLEEP(RES_VDD1, DEV_GRP_P1, -1, -1), 723 TWL_REMAP_SLEEP(RES_VDD2, DEV_GRP_P1, -1, -1), 724 { 0, 0 }, 725 }; 726 727 static struct twl4030_power_data omap3_reset = { 728 .scripts = omap3_reset_scripts, 729 .num = ARRAY_SIZE(omap3_reset_scripts), 730 .resource_config = omap3_rconfig, 731 }; 732 733 /* Recommended generic default idle configuration for off-idle */ 734 735 /* Broadcast message to put res to sleep */ 736 static struct twl4030_ins omap3_idle_sleep_on_seq[] = { 737 TWL_RESOURCE_GROUP_SLEEP(RES_GRP_ALL, RES_TYPE_ALL, 0), 738 }; 739 740 static struct twl4030_script omap3_idle_sleep_on_script = { 741 .script = omap3_idle_sleep_on_seq, 742 .size = ARRAY_SIZE(omap3_idle_sleep_on_seq), 743 .flags = TWL4030_SLEEP_SCRIPT, 744 }; 745 746 /* Broadcast message to put res to active */ 747 static struct twl4030_ins omap3_idle_wakeup_p12_seq[] = { 748 TWL_RESOURCE_GROUP_ACTIVE(RES_GRP_ALL, RES_TYPE_ALL, 0), 749 }; 750 751 static struct twl4030_script omap3_idle_wakeup_p12_script = { 752 .script = omap3_idle_wakeup_p12_seq, 753 .size = ARRAY_SIZE(omap3_idle_wakeup_p12_seq), 754 .flags = TWL4030_WAKEUP12_SCRIPT, 755 }; 756 757 /* Broadcast message to put res to active */ 758 static struct twl4030_ins omap3_idle_wakeup_p3_seq[] = { 759 TWL_RESOURCE_SET_ACTIVE(RES_CLKEN, 0x37), 760 TWL_RESOURCE_GROUP_ACTIVE(RES_GRP_ALL, RES_TYPE_ALL, 0), 761 }; 762 763 static struct twl4030_script omap3_idle_wakeup_p3_script = { 764 .script = omap3_idle_wakeup_p3_seq, 765 .size = ARRAY_SIZE(omap3_idle_wakeup_p3_seq), 766 .flags = TWL4030_WAKEUP3_SCRIPT, 767 }; 768 769 static struct twl4030_script *omap3_idle_scripts[] = { 770 &omap3_idle_wakeup_p12_script, 771 &omap3_idle_wakeup_p3_script, 772 &omap3_wrst_script, 773 &omap3_idle_sleep_on_script, 774 }; 775 776 /* 777 * Recommended configuration based on "Recommended Sleep 778 * Sequences for the Zoom Platform": 779 * http://omappedia.com/wiki/File:Recommended_Sleep_Sequences_Zoom.pdf 780 * Note that the type1 and type2 seem to be just the init order number 781 * for type1 and type2 groups as specified in the document mentioned 782 * above. 783 */ 784 static struct twl4030_resconfig omap3_idle_rconfig[] = { 785 TWL_REMAP_SLEEP(RES_VAUX1, TWL4030_RESCONFIG_UNDEF, 0, 0), 786 TWL_REMAP_SLEEP(RES_VAUX2, TWL4030_RESCONFIG_UNDEF, 0, 0), 787 TWL_REMAP_SLEEP(RES_VAUX3, TWL4030_RESCONFIG_UNDEF, 0, 0), 788 TWL_REMAP_SLEEP(RES_VAUX4, TWL4030_RESCONFIG_UNDEF, 0, 0), 789 TWL_REMAP_SLEEP(RES_VMMC1, TWL4030_RESCONFIG_UNDEF, 0, 0), 790 TWL_REMAP_SLEEP(RES_VMMC2, TWL4030_RESCONFIG_UNDEF, 0, 0), 791 TWL_REMAP_OFF(RES_VPLL1, DEV_GRP_P1, 3, 1), 792 TWL_REMAP_SLEEP(RES_VPLL2, DEV_GRP_P1, 0, 0), 793 TWL_REMAP_SLEEP(RES_VSIM, TWL4030_RESCONFIG_UNDEF, 0, 0), 794 TWL_REMAP_SLEEP(RES_VDAC, TWL4030_RESCONFIG_UNDEF, 0, 0), 795 TWL_REMAP_SLEEP(RES_VINTANA1, TWL_DEV_GRP_P123, 1, 2), 796 TWL_REMAP_SLEEP(RES_VINTANA2, TWL_DEV_GRP_P123, 0, 2), 797 TWL_REMAP_SLEEP(RES_VINTDIG, TWL_DEV_GRP_P123, 1, 2), 798 TWL_REMAP_SLEEP(RES_VIO, TWL_DEV_GRP_P123, 2, 2), 799 TWL_REMAP_OFF(RES_VDD1, DEV_GRP_P1, 4, 1), 800 TWL_REMAP_OFF(RES_VDD2, DEV_GRP_P1, 3, 1), 801 TWL_REMAP_SLEEP(RES_VUSB_1V5, TWL4030_RESCONFIG_UNDEF, 0, 0), 802 TWL_REMAP_SLEEP(RES_VUSB_1V8, TWL4030_RESCONFIG_UNDEF, 0, 0), 803 TWL_REMAP_SLEEP(RES_VUSB_3V1, TWL_DEV_GRP_P123, 0, 0), 804 /* Resource #20 USB charge pump skipped */ 805 TWL_REMAP_SLEEP(RES_REGEN, TWL_DEV_GRP_P123, 2, 1), 806 TWL_REMAP_SLEEP(RES_NRES_PWRON, TWL_DEV_GRP_P123, 0, 1), 807 TWL_REMAP_SLEEP(RES_CLKEN, TWL_DEV_GRP_P123, 3, 2), 808 TWL_REMAP_SLEEP(RES_SYSEN, TWL_DEV_GRP_P123, 6, 1), 809 TWL_REMAP_SLEEP(RES_HFCLKOUT, DEV_GRP_P3, 0, 2), 810 TWL_REMAP_SLEEP(RES_32KCLKOUT, TWL_DEV_GRP_P123, 0, 0), 811 TWL_REMAP_SLEEP(RES_RESET, TWL_DEV_GRP_P123, 6, 0), 812 TWL_REMAP_SLEEP(RES_MAIN_REF, TWL_DEV_GRP_P123, 0, 0), 813 { /* Terminator */ }, 814 }; 815 816 static struct twl4030_power_data omap3_idle = { 817 .scripts = omap3_idle_scripts, 818 .num = ARRAY_SIZE(omap3_idle_scripts), 819 .resource_config = omap3_idle_rconfig, 820 }; 821 822 /* Disable 32 KiHz oscillator during idle */ 823 static struct twl4030_resconfig osc_off_rconfig[] = { 824 TWL_REMAP_OFF(RES_CLKEN, DEV_GRP_P1 | DEV_GRP_P3, 3, 2), 825 { /* Terminator */ }, 826 }; 827 828 static struct twl4030_power_data osc_off_idle = { 829 .scripts = omap3_idle_scripts, 830 .num = ARRAY_SIZE(omap3_idle_scripts), 831 .resource_config = omap3_idle_rconfig, 832 .board_config = osc_off_rconfig, 833 }; 834 835 static struct twl4030_power_data omap3_idle_ac_quirk = { 836 .scripts = omap3_idle_scripts, 837 .num = ARRAY_SIZE(omap3_idle_scripts), 838 .resource_config = omap3_idle_rconfig, 839 .ac_charger_quirk = true, 840 }; 841 842 static struct twl4030_power_data omap3_idle_ac_quirk_osc_off = { 843 .scripts = omap3_idle_scripts, 844 .num = ARRAY_SIZE(omap3_idle_scripts), 845 .resource_config = omap3_idle_rconfig, 846 .board_config = osc_off_rconfig, 847 .ac_charger_quirk = true, 848 }; 849 850 static const struct of_device_id twl4030_power_of_match[] = { 851 { 852 .compatible = "ti,twl4030-power", 853 }, 854 { 855 .compatible = "ti,twl4030-power-reset", 856 .data = &omap3_reset, 857 }, 858 { 859 .compatible = "ti,twl4030-power-idle", 860 .data = &omap3_idle, 861 }, 862 { 863 .compatible = "ti,twl4030-power-idle-osc-off", 864 .data = &osc_off_idle, 865 }, 866 { 867 .compatible = "ti,twl4030-power-omap3-sdp", 868 .data = &omap3_idle_ac_quirk, 869 }, 870 { 871 .compatible = "ti,twl4030-power-omap3-ldp", 872 .data = &omap3_idle_ac_quirk_osc_off, 873 }, 874 { 875 .compatible = "ti,twl4030-power-omap3-evm", 876 .data = &omap3_idle_ac_quirk, 877 }, 878 { }, 879 }; 880 MODULE_DEVICE_TABLE(of, twl4030_power_of_match); 881 #endif /* CONFIG_OF */ 882 883 static int twl4030_power_probe(struct platform_device *pdev) 884 { 885 const struct twl4030_power_data *pdata = dev_get_platdata(&pdev->dev); 886 struct device_node *node = pdev->dev.of_node; 887 const struct of_device_id *match; 888 int err = 0; 889 int err2 = 0; 890 u8 val; 891 892 if (!pdata && !node) { 893 dev_err(&pdev->dev, "Platform data is missing\n"); 894 return -EINVAL; 895 } 896 897 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1, 898 TWL4030_PM_MASTER_PROTECT_KEY); 899 err |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 900 TWL4030_PM_MASTER_KEY_CFG2, 901 TWL4030_PM_MASTER_PROTECT_KEY); 902 903 if (err) { 904 pr_err("TWL4030 Unable to unlock registers\n"); 905 return err; 906 } 907 908 match = of_match_device(of_match_ptr(twl4030_power_of_match), 909 &pdev->dev); 910 if (match && match->data) 911 pdata = match->data; 912 913 if (pdata) { 914 err = twl4030_power_configure_scripts(pdata); 915 if (err) { 916 pr_err("TWL4030 failed to load scripts\n"); 917 goto relock; 918 } 919 err = twl4030_power_configure_resources(pdata); 920 if (err) { 921 pr_err("TWL4030 failed to configure resource\n"); 922 goto relock; 923 } 924 } 925 926 /* Board has to be wired properly to use this feature */ 927 if (twl4030_power_use_poweroff(pdata, node) && !pm_power_off) { 928 /* Default for SEQ_OFFSYNC is set, lets ensure this */ 929 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &val, 930 TWL4030_PM_MASTER_CFG_P123_TRANSITION); 931 if (err) { 932 pr_warning("TWL4030 Unable to read registers\n"); 933 934 } else if (!(val & SEQ_OFFSYNC)) { 935 val |= SEQ_OFFSYNC; 936 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, val, 937 TWL4030_PM_MASTER_CFG_P123_TRANSITION); 938 if (err) { 939 pr_err("TWL4030 Unable to setup SEQ_OFFSYNC\n"); 940 goto relock; 941 } 942 } 943 944 pm_power_off = twl4030_power_off; 945 } 946 947 relock: 948 err2 = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0, 949 TWL4030_PM_MASTER_PROTECT_KEY); 950 if (err2) { 951 pr_err("TWL4030 Unable to relock registers\n"); 952 return err2; 953 } 954 955 return err; 956 } 957 958 static int twl4030_power_remove(struct platform_device *pdev) 959 { 960 return 0; 961 } 962 963 static struct platform_driver twl4030_power_driver = { 964 .driver = { 965 .name = "twl4030_power", 966 .of_match_table = of_match_ptr(twl4030_power_of_match), 967 }, 968 .probe = twl4030_power_probe, 969 .remove = twl4030_power_remove, 970 }; 971 972 module_platform_driver(twl4030_power_driver); 973 974 MODULE_AUTHOR("Nokia Corporation"); 975 MODULE_AUTHOR("Texas Instruments, Inc."); 976 MODULE_DESCRIPTION("Power management for TWL4030"); 977 MODULE_LICENSE("GPL"); 978 MODULE_ALIAS("platform:twl4030_power"); 979