twl4030-power.c (26519B)
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/mfd/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 35static 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 109static 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 */ 144enum { 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 187static 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); 195out: 196 return err; 197} 198 199static 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); 215out: 216 return err; 217} 218 219static 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 244static 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); 260out: 261 if (err) 262 pr_err("TWL4030 wakeup sequence for P3 config error\n"); 263 return err; 264} 265 266static int 267twl4030_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 311out: 312 if (err) 313 pr_err("TWL4030 wakeup sequence for P1 and P2" \ 314 "config error\n"); 315 return err; 316} 317 318static 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 331static 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); 366out: 367 if (err) 368 pr_err("TWL4030 warmreset seq config error\n"); 369 return err; 370} 371 372static 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 464static 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_warn("TWL4030: Bad order of scripts (sleep script before wakeup) Leads to boot failure on some boards\n"); 506 err = twl4030_config_sleep_sequence(address); 507 } 508out: 509 return err; 510} 511 512int twl4030_remove_script(u8 flags) 513{ 514 int err = 0; 515 516 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1, 517 TWL4030_PM_MASTER_PROTECT_KEY); 518 if (err) { 519 pr_err("twl4030: unable to unlock PROTECT_KEY\n"); 520 return err; 521 } 522 523 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2, 524 TWL4030_PM_MASTER_PROTECT_KEY); 525 if (err) { 526 pr_err("twl4030: unable to unlock PROTECT_KEY\n"); 527 return err; 528 } 529 530 if (flags & TWL4030_WRST_SCRIPT) { 531 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT, 532 R_SEQ_ADD_WARM); 533 if (err) 534 return err; 535 } 536 if (flags & TWL4030_WAKEUP12_SCRIPT) { 537 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT, 538 R_SEQ_ADD_S2A12); 539 if (err) 540 return err; 541 } 542 if (flags & TWL4030_WAKEUP3_SCRIPT) { 543 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT, 544 R_SEQ_ADD_S2A3); 545 if (err) 546 return err; 547 } 548 if (flags & TWL4030_SLEEP_SCRIPT) { 549 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT, 550 R_SEQ_ADD_A2S); 551 if (err) 552 return err; 553 } 554 555 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0, 556 TWL4030_PM_MASTER_PROTECT_KEY); 557 if (err) 558 pr_err("TWL4030 Unable to relock registers\n"); 559 560 return err; 561} 562 563static int 564twl4030_power_configure_scripts(const struct twl4030_power_data *pdata) 565{ 566 int err; 567 int i; 568 u8 address = twl4030_start_script_address; 569 570 for (i = 0; i < pdata->num; i++) { 571 err = load_twl4030_script(pdata, pdata->scripts[i], address); 572 if (err) 573 return err; 574 address += pdata->scripts[i]->size; 575 } 576 577 return 0; 578} 579 580static void twl4030_patch_rconfig(struct twl4030_resconfig *common, 581 struct twl4030_resconfig *board) 582{ 583 while (common->resource) { 584 struct twl4030_resconfig *b = board; 585 586 while (b->resource) { 587 if (b->resource == common->resource) { 588 *common = *b; 589 break; 590 } 591 b++; 592 } 593 common++; 594 } 595} 596 597static int 598twl4030_power_configure_resources(const struct twl4030_power_data *pdata) 599{ 600 struct twl4030_resconfig *resconfig = pdata->resource_config; 601 struct twl4030_resconfig *boardconf = pdata->board_config; 602 int err; 603 604 if (resconfig) { 605 if (boardconf) 606 twl4030_patch_rconfig(resconfig, boardconf); 607 608 while (resconfig->resource) { 609 err = twl4030_configure_resource(resconfig); 610 if (err) 611 return err; 612 resconfig++; 613 } 614 } 615 616 return 0; 617} 618 619static int twl4030_starton_mask_and_set(u8 bitmask, u8 bitvalues) 620{ 621 u8 regs[3] = { TWL4030_PM_MASTER_CFG_P1_TRANSITION, 622 TWL4030_PM_MASTER_CFG_P2_TRANSITION, 623 TWL4030_PM_MASTER_CFG_P3_TRANSITION, }; 624 u8 val; 625 int i, err; 626 627 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1, 628 TWL4030_PM_MASTER_PROTECT_KEY); 629 if (err) 630 goto relock; 631 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 632 TWL4030_PM_MASTER_KEY_CFG2, 633 TWL4030_PM_MASTER_PROTECT_KEY); 634 if (err) 635 goto relock; 636 637 for (i = 0; i < sizeof(regs); i++) { 638 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, 639 &val, regs[i]); 640 if (err) 641 break; 642 val = (~bitmask & val) | (bitmask & bitvalues); 643 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 644 val, regs[i]); 645 if (err) 646 break; 647 } 648 649 if (err) 650 pr_err("TWL4030 Register access failed: %i\n", err); 651 652relock: 653 return twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0, 654 TWL4030_PM_MASTER_PROTECT_KEY); 655} 656 657/* 658 * In master mode, start the power off sequence. 659 * After a successful execution, TWL shuts down the power to the SoC 660 * and all peripherals connected to it. 661 */ 662void twl4030_power_off(void) 663{ 664 int err; 665 666 /* Disable start on charger or VBUS as it can break poweroff */ 667 err = twl4030_starton_mask_and_set(STARTON_VBUS | STARTON_CHG, 0); 668 if (err) 669 pr_err("TWL4030 Unable to configure start-up\n"); 670 671 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, PWR_DEVOFF, 672 TWL4030_PM_MASTER_P1_SW_EVENTS); 673 if (err) 674 pr_err("TWL4030 Unable to power off\n"); 675} 676 677static bool twl4030_power_use_poweroff(const struct twl4030_power_data *pdata, 678 struct device_node *node) 679{ 680 if (pdata && pdata->use_poweroff) 681 return true; 682 683 if (of_property_read_bool(node, "ti,system-power-controller")) 684 return true; 685 686 if (of_property_read_bool(node, "ti,use_poweroff")) 687 return true; 688 689 return false; 690} 691 692#ifdef CONFIG_OF 693 694/* Generic warm reset configuration for omap3 */ 695 696static struct twl4030_ins omap3_wrst_seq[] = { 697 TWL_RESOURCE_OFF(RES_NRES_PWRON), 698 TWL_RESOURCE_OFF(RES_RESET), 699 TWL_RESOURCE_RESET(RES_MAIN_REF), 700 TWL_RESOURCE_GROUP_RESET(RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2), 701 TWL_RESOURCE_RESET(RES_VUSB_3V1), 702 TWL_RESOURCE_RESET(RES_VMMC1), 703 TWL_RESOURCE_GROUP_RESET(RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1), 704 TWL_RESOURCE_GROUP_RESET(RES_GRP_RC, RES_TYPE_ALL, RES_TYPE2_R0), 705 TWL_RESOURCE_ON(RES_RESET), 706 TWL_RESOURCE_ON(RES_NRES_PWRON), 707}; 708 709static struct twl4030_script omap3_wrst_script = { 710 .script = omap3_wrst_seq, 711 .size = ARRAY_SIZE(omap3_wrst_seq), 712 .flags = TWL4030_WRST_SCRIPT, 713}; 714 715static struct twl4030_script *omap3_reset_scripts[] = { 716 &omap3_wrst_script, 717}; 718 719static struct twl4030_resconfig omap3_rconfig[] = { 720 TWL_REMAP_SLEEP(RES_HFCLKOUT, DEV_GRP_P3, -1, -1), 721 TWL_REMAP_SLEEP(RES_VDD1, DEV_GRP_P1, -1, -1), 722 TWL_REMAP_SLEEP(RES_VDD2, DEV_GRP_P1, -1, -1), 723 { 0, 0 }, 724}; 725 726static struct twl4030_power_data omap3_reset = { 727 .scripts = omap3_reset_scripts, 728 .num = ARRAY_SIZE(omap3_reset_scripts), 729 .resource_config = omap3_rconfig, 730}; 731 732/* Recommended generic default idle configuration for off-idle */ 733 734/* Broadcast message to put res to sleep */ 735static struct twl4030_ins omap3_idle_sleep_on_seq[] = { 736 TWL_RESOURCE_GROUP_SLEEP(RES_GRP_ALL, RES_TYPE_ALL, 0), 737}; 738 739static struct twl4030_script omap3_idle_sleep_on_script = { 740 .script = omap3_idle_sleep_on_seq, 741 .size = ARRAY_SIZE(omap3_idle_sleep_on_seq), 742 .flags = TWL4030_SLEEP_SCRIPT, 743}; 744 745/* Broadcast message to put res to active */ 746static struct twl4030_ins omap3_idle_wakeup_p12_seq[] = { 747 TWL_RESOURCE_GROUP_ACTIVE(RES_GRP_ALL, RES_TYPE_ALL, 0), 748}; 749 750static struct twl4030_script omap3_idle_wakeup_p12_script = { 751 .script = omap3_idle_wakeup_p12_seq, 752 .size = ARRAY_SIZE(omap3_idle_wakeup_p12_seq), 753 .flags = TWL4030_WAKEUP12_SCRIPT, 754}; 755 756/* Broadcast message to put res to active */ 757static struct twl4030_ins omap3_idle_wakeup_p3_seq[] = { 758 TWL_RESOURCE_SET_ACTIVE(RES_CLKEN, 0x37), 759 TWL_RESOURCE_GROUP_ACTIVE(RES_GRP_ALL, RES_TYPE_ALL, 0), 760}; 761 762static struct twl4030_script omap3_idle_wakeup_p3_script = { 763 .script = omap3_idle_wakeup_p3_seq, 764 .size = ARRAY_SIZE(omap3_idle_wakeup_p3_seq), 765 .flags = TWL4030_WAKEUP3_SCRIPT, 766}; 767 768static struct twl4030_script *omap3_idle_scripts[] = { 769 &omap3_idle_wakeup_p12_script, 770 &omap3_idle_wakeup_p3_script, 771 &omap3_wrst_script, 772 &omap3_idle_sleep_on_script, 773}; 774 775/* 776 * Recommended configuration based on "Recommended Sleep 777 * Sequences for the Zoom Platform": 778 * http://omappedia.com/wiki/File:Recommended_Sleep_Sequences_Zoom.pdf 779 * Note that the type1 and type2 seem to be just the init order number 780 * for type1 and type2 groups as specified in the document mentioned 781 * above. 782 */ 783static struct twl4030_resconfig omap3_idle_rconfig[] = { 784 TWL_REMAP_SLEEP(RES_VAUX1, TWL4030_RESCONFIG_UNDEF, 0, 0), 785 TWL_REMAP_SLEEP(RES_VAUX2, TWL4030_RESCONFIG_UNDEF, 0, 0), 786 TWL_REMAP_SLEEP(RES_VAUX3, TWL4030_RESCONFIG_UNDEF, 0, 0), 787 TWL_REMAP_SLEEP(RES_VAUX4, TWL4030_RESCONFIG_UNDEF, 0, 0), 788 TWL_REMAP_SLEEP(RES_VMMC1, TWL4030_RESCONFIG_UNDEF, 0, 0), 789 TWL_REMAP_SLEEP(RES_VMMC2, TWL4030_RESCONFIG_UNDEF, 0, 0), 790 TWL_REMAP_OFF(RES_VPLL1, DEV_GRP_P1, 3, 1), 791 TWL_REMAP_SLEEP(RES_VPLL2, DEV_GRP_P1, 0, 0), 792 TWL_REMAP_SLEEP(RES_VSIM, TWL4030_RESCONFIG_UNDEF, 0, 0), 793 TWL_REMAP_SLEEP(RES_VDAC, TWL4030_RESCONFIG_UNDEF, 0, 0), 794 TWL_REMAP_SLEEP(RES_VINTANA1, TWL_DEV_GRP_P123, 1, 2), 795 TWL_REMAP_SLEEP(RES_VINTANA2, TWL_DEV_GRP_P123, 0, 2), 796 TWL_REMAP_SLEEP(RES_VINTDIG, TWL_DEV_GRP_P123, 1, 2), 797 TWL_REMAP_SLEEP(RES_VIO, TWL_DEV_GRP_P123, 2, 2), 798 TWL_REMAP_OFF(RES_VDD1, DEV_GRP_P1, 4, 1), 799 TWL_REMAP_OFF(RES_VDD2, DEV_GRP_P1, 3, 1), 800 TWL_REMAP_SLEEP(RES_VUSB_1V5, TWL4030_RESCONFIG_UNDEF, 0, 0), 801 TWL_REMAP_SLEEP(RES_VUSB_1V8, TWL4030_RESCONFIG_UNDEF, 0, 0), 802 TWL_REMAP_SLEEP(RES_VUSB_3V1, TWL_DEV_GRP_P123, 0, 0), 803 /* Resource #20 USB charge pump skipped */ 804 TWL_REMAP_SLEEP(RES_REGEN, TWL_DEV_GRP_P123, 2, 1), 805 TWL_REMAP_SLEEP(RES_NRES_PWRON, TWL_DEV_GRP_P123, 0, 1), 806 TWL_REMAP_SLEEP(RES_CLKEN, TWL_DEV_GRP_P123, 3, 2), 807 TWL_REMAP_SLEEP(RES_SYSEN, TWL_DEV_GRP_P123, 6, 1), 808 TWL_REMAP_SLEEP(RES_HFCLKOUT, DEV_GRP_P3, 0, 2), 809 TWL_REMAP_SLEEP(RES_32KCLKOUT, TWL_DEV_GRP_P123, 0, 0), 810 TWL_REMAP_SLEEP(RES_RESET, TWL_DEV_GRP_P123, 6, 0), 811 TWL_REMAP_SLEEP(RES_MAIN_REF, TWL_DEV_GRP_P123, 0, 0), 812 { /* Terminator */ }, 813}; 814 815static struct twl4030_power_data omap3_idle = { 816 .scripts = omap3_idle_scripts, 817 .num = ARRAY_SIZE(omap3_idle_scripts), 818 .resource_config = omap3_idle_rconfig, 819}; 820 821/* Disable 32 KiHz oscillator during idle */ 822static struct twl4030_resconfig osc_off_rconfig[] = { 823 TWL_REMAP_OFF(RES_CLKEN, DEV_GRP_P1 | DEV_GRP_P3, 3, 2), 824 { /* Terminator */ }, 825}; 826 827static struct twl4030_power_data osc_off_idle = { 828 .scripts = omap3_idle_scripts, 829 .num = ARRAY_SIZE(omap3_idle_scripts), 830 .resource_config = omap3_idle_rconfig, 831 .board_config = osc_off_rconfig, 832}; 833 834static struct twl4030_power_data omap3_idle_ac_quirk = { 835 .scripts = omap3_idle_scripts, 836 .num = ARRAY_SIZE(omap3_idle_scripts), 837 .resource_config = omap3_idle_rconfig, 838 .ac_charger_quirk = true, 839}; 840 841static struct twl4030_power_data omap3_idle_ac_quirk_osc_off = { 842 .scripts = omap3_idle_scripts, 843 .num = ARRAY_SIZE(omap3_idle_scripts), 844 .resource_config = omap3_idle_rconfig, 845 .board_config = osc_off_rconfig, 846 .ac_charger_quirk = true, 847}; 848 849static const struct of_device_id twl4030_power_of_match[] = { 850 { 851 .compatible = "ti,twl4030-power", 852 }, 853 { 854 .compatible = "ti,twl4030-power-reset", 855 .data = &omap3_reset, 856 }, 857 { 858 .compatible = "ti,twl4030-power-idle", 859 .data = &omap3_idle, 860 }, 861 { 862 .compatible = "ti,twl4030-power-idle-osc-off", 863 .data = &osc_off_idle, 864 }, 865 { 866 .compatible = "ti,twl4030-power-omap3-sdp", 867 .data = &omap3_idle_ac_quirk, 868 }, 869 { 870 .compatible = "ti,twl4030-power-omap3-ldp", 871 .data = &omap3_idle_ac_quirk_osc_off, 872 }, 873 { 874 .compatible = "ti,twl4030-power-omap3-evm", 875 .data = &omap3_idle_ac_quirk, 876 }, 877 { }, 878}; 879MODULE_DEVICE_TABLE(of, twl4030_power_of_match); 880#endif /* CONFIG_OF */ 881 882static int twl4030_power_probe(struct platform_device *pdev) 883{ 884 const struct twl4030_power_data *pdata = dev_get_platdata(&pdev->dev); 885 struct device_node *node = pdev->dev.of_node; 886 const struct of_device_id *match; 887 int err = 0; 888 int err2 = 0; 889 u8 val; 890 891 if (!pdata && !node) { 892 dev_err(&pdev->dev, "Platform data is missing\n"); 893 return -EINVAL; 894 } 895 896 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1, 897 TWL4030_PM_MASTER_PROTECT_KEY); 898 err |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 899 TWL4030_PM_MASTER_KEY_CFG2, 900 TWL4030_PM_MASTER_PROTECT_KEY); 901 902 if (err) { 903 pr_err("TWL4030 Unable to unlock registers\n"); 904 return err; 905 } 906 907 match = of_match_device(of_match_ptr(twl4030_power_of_match), 908 &pdev->dev); 909 if (match && match->data) 910 pdata = match->data; 911 912 if (pdata) { 913 err = twl4030_power_configure_scripts(pdata); 914 if (err) { 915 pr_err("TWL4030 failed to load scripts\n"); 916 goto relock; 917 } 918 err = twl4030_power_configure_resources(pdata); 919 if (err) { 920 pr_err("TWL4030 failed to configure resource\n"); 921 goto relock; 922 } 923 } 924 925 /* Board has to be wired properly to use this feature */ 926 if (twl4030_power_use_poweroff(pdata, node) && !pm_power_off) { 927 /* Default for SEQ_OFFSYNC is set, lets ensure this */ 928 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &val, 929 TWL4030_PM_MASTER_CFG_P123_TRANSITION); 930 if (err) { 931 pr_warn("TWL4030 Unable to read registers\n"); 932 } else if (!(val & SEQ_OFFSYNC)) { 933 val |= SEQ_OFFSYNC; 934 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, val, 935 TWL4030_PM_MASTER_CFG_P123_TRANSITION); 936 if (err) { 937 pr_err("TWL4030 Unable to setup SEQ_OFFSYNC\n"); 938 goto relock; 939 } 940 } 941 942 pm_power_off = twl4030_power_off; 943 } 944 945relock: 946 err2 = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0, 947 TWL4030_PM_MASTER_PROTECT_KEY); 948 if (err2) { 949 pr_err("TWL4030 Unable to relock registers\n"); 950 return err2; 951 } 952 953 return err; 954} 955 956static int twl4030_power_remove(struct platform_device *pdev) 957{ 958 return 0; 959} 960 961static struct platform_driver twl4030_power_driver = { 962 .driver = { 963 .name = "twl4030_power", 964 .of_match_table = of_match_ptr(twl4030_power_of_match), 965 }, 966 .probe = twl4030_power_probe, 967 .remove = twl4030_power_remove, 968}; 969 970module_platform_driver(twl4030_power_driver); 971 972MODULE_AUTHOR("Nokia Corporation"); 973MODULE_AUTHOR("Texas Instruments, Inc."); 974MODULE_DESCRIPTION("Power management for TWL4030"); 975MODULE_LICENSE("GPL"); 976MODULE_ALIAS("platform:twl4030_power");